数组名不是常量指针,而是类型为int[5]的独立实体;它在多数表达式中隐式转换为int*,但sizeof(arr)返回数组总字节数,arr++非法,而指针变量p++合法且sizeof(p)仅返回指针大小。

不是。数组名不是常量指针,而是一个具有特定类型和行为的独立语言实体;它在多数表达式中会隐式转换为指向首元素的指针(int* 类型),但本身既不是指针变量,也不是 const int* 或 int* const 这类“常量指针”或“指针常量”。
为什么 arr++ 会编译失败?
因为数组名 arr 不是变量,没有可修改的存储位置。它不占用栈空间,也不像指针变量那样持有地址值——它只是编译器用来标记一段连续内存起始位置的符号名。
-
int arr[5];中的arr类型是int[5],不是int* -
arr++尝试对非左值(non-lvalue)做自增,等价于试图给一个地址常量赋新值,语法非法 - 而
int* p = arr;后的p++合法,因为p是变量,有可读写地址
sizeof(arr) 返回整个数组大小,而 sizeof(p) 只返回指针大小
这是最直接暴露本质差异的地方:类型信息未丢失。数组名携带维度信息,指针不携带。
-
int arr[10]; sizeof(arr)→ 返回40(假设int为 4 字节) -
int* p = arr; sizeof(p)→ 返回8(64 位系统下指针大小) - 函数参数中
void f(int a[10])实际等价于void f(int* a),此时a已退化为普通指针,sizeof(a)不再是数组大小
数组名能用 &arr 和 &arr[0] 区分出两种不同类型的指针
同一个数组,取地址能得到两个类型不同的指针值,说明数组名背后有更精细的类型系统支持。
-
&arr[0]类型是int*,指向单个int -
&arr类型是int(*)[10](指向含 10 个int的数组的指针),值虽与&arr[0]相同,但算术运算步长不同:(&arr) + 1跳过整个 10 元素块,(&arr[0]) + 1只跳过 1 个int - 这种差异无法用“常量指针”概念解释,只源于数组类型本身的维度语义
真正容易被忽略的,是数组名在模板推导、decltype 和重载解析中保留完整类型的能力——比如 decltype(arr) 是 int[10],不是 int*。一旦你开始写泛型代码或调试类型错误,这个区别就不再是理论问题,而是编译器报错的第一现场。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











