You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中数组与sizeof()的疑问:数组名是否为指针?

数组名与指针退化的核心问题解答

核心结论先明确

数组名不是普通指针,但在绝大多数场景下会被C语言隐式转换为指向数组首元素的指针(也就是常说的“退化”)。只有少数例外场景中,数组名会保留原有的数组类型,这就是你看到sizeof结果差异的根本原因。


问题1:数组名并非指向首元素的指针?那它是什么?为何支持指针算术?

  • 数组名是数组类型的标识符。比如定义int arr[5];,arr的实际类型是int[5](包含5个int元素的数组),而非int*(指向int的指针)。
  • 你能对数组名做指针算术(比如arr+1)或下标访问(arr[i]),本质是C标准的规定:当数组名出现在表达式中(除特殊场景外),会自动转换为指向首元素的指针。转换后arr+i等价于&arr[i],arr[i]自然等价于*(arr+i)——看起来像是数组名本身支持这些操作,实则是转换后的指针在起作用。

问题2:数组名确实是首元素指针?那为何与退化后的指针存储的信息不同?

  • 数组名不是首元素指针,只是会被隐式转换。而sizeof(arr)就是不会触发退化的例外场景之一:当数组名作为sizeof的操作数时,它保持原有数组类型,因此sizeof(arr)计算的是整个数组的总字节数(比如5个int元素就是5*sizeof(int))。
  • 当数组作为函数参数传递时,C标准会强制将参数的数组类型调整为指针类型。比如void func(int arr[5])会被编译器自动解析为void func(int* arr),此时函数内部的arr就是普通指针,sizeof(arr)返回的自然是指针大小(64位机器上为8字节)。
  • 除了sizeof,还有两个常见的非退化场景:
    • 数组名作为&的操作数时:&arr得到的是指向整个数组的指针(类型为int (*)[5]),而非指向首元素的指针(虽然两者内存地址值相同,但类型不同,指针算术的行为也不一样)。
    • 用字符串字面量初始化字符数组时:char str[] = "hello";中的str保持数组类型,sizeof(str)会返回包含终止符的总字节数(6字节)。

代码示例验证

#include <stdio.h>

void test(int arr[5]) {
    // 函数内arr已退化为指针,64位机输出8
    printf("函数内sizeof(arr):%zu\n", sizeof(arr));
}

int main() {
    int arr[5] = {1,2,3,4,5};
    // 主函数内arr保持数组类型,输出20(假设int为4字节)
    printf("主函数内sizeof(arr):%zu\n", sizeof(arr));
    // arr转换为指向首元素的指针,地址与&arr[0]相同
    printf("arr(首元素指针):%p\n", arr);
    // &arr是指向整个数组的指针,地址值相同但类型不同
    printf("&arr(数组指针):%p\n", &arr);
    test(arr);
    return 0;
}

内容的提问来源于stack exchange,提问作者Kotaka Danski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 17:12:53