sizeof(arr)返回数组总字节数而非元素个数,计算元素数需用sizeof(arr)/sizeof(*arr);传入函数后arr退化为指针,sizeof失效;动态分配数组不能用此法求长度。

sizeof(arr) 返回数组总字节数,不是元素个数
很多人误以为 sizeof(arr) 得到的是数组长度(比如 int arr[5] 返回 5),其实它返回的是整个数组占的字节数:5 × sizeof(int)。在 64 位系统上,sizeof(int) 通常是 4,所以结果是 20;若用 long long arr[3],则返回 3 × 8 = 24。
要算元素个数,得手动除: sizeof(arr) / sizeof(arr[0]) 或更安全地写成 sizeof(arr) / sizeof(*arr) —— 后者不依赖下标合法性,也适用于 char arr[10] 这类场景。
- 不能对动态分配的数组(如
new int[10])用这个技巧,因为sizeof对指针返回的是指针大小,不是所指内存大小 -
arr必须是**定义在当前作用域的数组变量**,传进函数后就退化成指针,sizeof失效
sizeof(p) 返回指针变量本身大小,与目标无关
sizeof(p) 的结果只取决于平台和指针类型,跟 p 指向哪、指向多少数据完全无关。在 64 位系统上几乎总是 8;32 位系统上是 4。哪怕你写 int* p = new int[1000000],sizeof(p) 还是 8。
这导致一个常见误判:有人用 sizeof(p)/sizeof(*p) 试图算动态数组长度,结果永远是 8 / 4 = 2(64 位下),纯属误导。
- 函数参数里写
void func(int arr[])或void func(int* arr)效果一样 ——arr在函数体内就是指针,sizeof(arr)永远是指针大小 - 如果真需要传递数组大小,必须额外加一个参数,比如
func(int arr[], size_t n)
&arr 和 arr 的地址值相同,但类型和 sizeof 行为完全不同
假设 int arr[10],那么 arr、&arr[0]、&arr 这三个表达式的数值地址通常一样,但类型不同:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
arr类型是int[10],但在多数上下文自动转为int*(指向首元素) -
&arr[0]类型明确是int* -
&arr类型是int (*)[10](指向整个数组的指针),这是关键区别
后果很实际:指针算术中,arr + 1 跳过 4 字节(一个 int),而 (&arr) + 1 跳过 40 字节(整个数组)。sizeof(&arr) 仍是 8(它是个指针变量),但 sizeof(arr) 是 40 —— 这说明 &arr 的“指向对象”是数组整体,不是单个元素。
数组名不是指针,但能隐式转成指针常量
数组名 arr 本质是一个“不可修改的地址常量”,不是变量。你不能写 arr++ 或 arr = nullptr,编译器直接报错。而指针变量 int* p 可以随时重赋值、自增、参与复杂运算。
这种“可转换但不可赋值”的特性,正是混淆的根源:很多地方(如函数调用、+ 运算)它表现得像指针,但 sizeof、&、绑定引用(int (&r)[10] = arr;)时,它立刻暴露数组本体身份。
最容易被忽略的一点:当数组作为模板参数或 auto 推导时,auto x = arr; 推出的是 int*(退化),但 auto& y = arr; 才保留数组类型 —— 这直接影响 sizeof(y) 是否还能拿到原始大小。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










