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;
}