C语言中,数组到指针的转换(也称为 数组衰退 或 decay)是指数组在大多数上下文中会被隐式地转换为指向其第一个元素的指针。这种行为被称为 '数组衰退'。该转换使得数组的名称在表达式中通常表现为指针。

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

推荐文档