1、数组到指针的转换
当使用一个数组的名称时,除非它被用作 sizeof
操作符的参数或用于一元操作符 &
,数组会自动衰退为指向其第一个元素的指针。
1)作为函数参数
#include <stdio.h> int main() { int arr[5] = {1, 2, 3, 4, 5}; // arr 衰退为指向 arr[0] 的指针 int *ptr = arr; // 打印指针所指向的值 printf("%d\n", *ptr); // 输出 1 printf("%d\n", *(ptr + 1)); // 输出 2 return 0; }
arr
的类型实际上是 int[5]
,但在大多数情况下(如在表达式中或作为函数参数),arr
会衰退为指向 arr[0]
的指针,类型为 int*
。arr
被隐式转换为 int*
,指向数组的第一个元素 arr[0]
。
2)作为函数参数
当数组作为函数参数时,它会自动转换为指针。也就是数组的大小信息会丢失,函数仅接收一个指向数组的指针。
#include <stdio.h> void printArray(int *arr, int size) { for (int i = 0; i < size; i++) { printf("%d ", arr[i]); } printf("\n"); } int main() { int arr[5] = {1, 2, 3, 4, 5}; printArray(arr, 5); // arr 衰退为指针 return 0; }
2、数组不会衰退为指针的情况
sizeof
不会触发数组衰退,返回整个数组的大小(以字节为单位)。&arr
会返回数组的地址而不是数组第一个元素的地址。
#include <stdio.h> int main() { // 声明一个大小为5的整型数组 int arr[5]; // 使用 sizeof 操作符计算整个数组的大小 // 假设每个 int 占用 4 字节,则输出 20 字节 printf("Size of array: %zu bytes\n", sizeof(arr)); // 使用 & 操作符获取数组地址 // `ptr` 指向数组的第一个元素 (arr[0]) int *ptr = arr; // `ptrArr` 指向整个数组的地址 int (*ptrArr)[5] = &arr; // 打印数组第一个元素的地址和整个数组的地址 // 打印数组第一个元素的地址 printf("Address of arr[0]: %p\n", (void*)ptr); // 打印整个数组的地址 printf("Address of array: %p\n", (void*)ptrArr); return 0; }
3、数组衰退的影响
由于数组会衰退为指针,数组的大小信息在大多数情况下会丢失。因此,传递数组给函数时,必须额外传递数组的大小信息,否则函数无法确定数组的大小。
#include <stdio.h> void printSize(int arr[]) { // 输出指针的大小 printf("Size inside function: %zu\n", sizeof(arr)); } int main() { int arr[5] = {1, 2, 3, 4, 5}; // 输出数组的大小 (20字节, 假设每个int是4字节) printf("Size of array: %zu\n", sizeof(arr)); // 输出指针的大小 (通常是8字节,取决于平台) printSize(arr); return 0; }