数组名不是指针但可隐式转换为指针;sizeof(arr) 返回数组总字节,sizeof(p) 返回指针大小;仅当作为sizeof、&操作数或字符串初始化时数组名不退化。

数组名不是指针,但能隐式转成指针
数组名在大多数表达式中会“退化”为指向首元素的指针,但这只是隐式转换,不是它本来就是指针。比如 int arr[5],arr 本身是类型为 int[5] 的左值,不是 int*;只有在做算术、赋值给指针变量等场景下,编译器才自动把它转成 &arr[0]。
一个关键证据:对数组名取地址——&arr 的类型是 int(*)[5](指向整个数组的指针),而 &arr[0] 或 arr(退化后)的类型才是 int*。这两个地址数值相同,但类型和含义完全不同。
sizeof(arr) 和 sizeof(p) 结果不同的根本原因
sizeof 是编译期运算符,结果取决于操作数的**静态类型**,不关心运行时值。所以:
-
sizeof(arr)中arr类型是int[5]→ 结果是5 * sizeof(int)(通常是 20) -
sizeof(p)中p类型是int*→ 结果是该平台指针大小(通常是 4 或 8) - 即使写
int* p = arr;,p仍是纯指针,sizeof(p)不会“记住”它曾指向数组
注意:sizeof 对函数参数里的数组形参也失效——因为形参 void f(int a[10]) 实际等价于 void f(int* a),sizeof(a) 永远是指针大小。
立即学习“C++免费学习笔记(深入)”;
什么时候数组名不能退化成指针?
只有三种情况数组名保持原类型(不退化),此时 sizeof 才能拿到真实长度:
- 作为
sizeof的操作数(如sizeof(arr)) - 作为一元
&的操作数(如&arr) - 作为字符串字面量初始化数组时(如
char s[] = "abc";,sizeof(s)是 4,含 ‘