C++数组sizeof运算符疑问:为何数组名操作数不返回指针大小?
数组场景下
sizeof运算符的工作机制解析 这是个非常经典的C/C++数组与指针混淆的问题,我来给你把逻辑理清楚~
先看你给出的代码:
int main() { int arr[] = {1,2,3,7,8}; std::size_t size = sizeof arr; std::cout << size << '\n'; }
你的疑问核心是:为什么arr看起来像指针(比如*arr能取首元素),但sizeof arr却返回整个数组的大小,而非指针的大小?
关键结论:数组名≠指针,只有在特定场景下才会退化为指针
数组名本身是数组类型的标识符,不是指针。但C/C++标准规定,数组名在大多数表达式场景中会被隐式转换为指向数组首元素的指针——但sizeof是少数几个不触发这个转换的例外场景之一。
1. sizeof(arr)的工作逻辑
当你直接对数组名使用sizeof时,编译器会直接识别arr的真实类型:这里arr是int[5](包含5个int元素的数组类型)。此时sizeof返回的是整个数组所占的总字节数,计算公式为:sizeof(元素类型) × 元素个数
在你的系统中int占4字节,所以就是4×5=20,这完全符合标准规定。
2. 为什么*arr能获取首元素?
这就是数组名退化为指针的典型场景:当数组名出现在普通表达式中(比如被解引用、赋值给指针变量等),它会自动转换成指向首元素的指针。所以*arr等价于*(arr + 0),本质是对指向首元素的指针做解引用操作,自然就能拿到数组的第一个元素。
补充几个数组名不退化的例外场景
除了sizeof(arr),还有两种情况数组名不会退化为指针:
- 取数组的地址:
&arr得到的是指向整个数组的指针,类型为int (*)[5],它的sizeof是系统的指针大小(4或8字节),但&arr + 1会直接跳过整个数组的内存空间。 - 用数组初始化数组引用:比如
int (&ref)[5] = arr;,这里ref是整个数组的引用,sizeof(ref)同样会返回20,因为它绑定的是完整的数组对象。
对比验证:数组名退化为指针的场景
如果把数组名赋值给指针变量,就能看到指针的sizeof结果了:
int* ptr = arr; // arr退化为指向首元素的指针 std::cout << sizeof(ptr) << '\n'; // 输出4或8,取决于你的系统位数
本质上,C/C++设计这个规则是为了兼顾数组使用的便利性(不用手动写指针)和底层操作的灵活性(比如直接获取数组总大小)。
内容的提问来源于stack exchange,提问作者Kakarot_7
相关产品推荐
相关产品推荐

