sizeof(数组名)返回整个数组字节数,因数组名在sizeof中不退化为指针,其类型为含长度的数组类型(如int[5]),故结果为元素个数×单元素大小;而sizeof(指针)仅返回该指针变量自身大小(32位为4字节,64位为8字节)。

sizeof(数组名) 返回的是整个数组字节数
因为 sizeof 是编译期运算符,它不看运行时值,只看操作数的**类型**。数组名在 sizeof 中不“退化”,它的类型就是 int[5]、char[10] 这类带长度的数组类型。所以 sizeof(a) 直接按 “元素个数 × 单个元素大小” 算。
例如:
int a[5] = {1,2,3,4,5};
printf("%zu\n", sizeof(a)); // 输出 20(假设 int 是 4 字节)这里 a 的类型是 int[5],不是 int*,所以结果跟指针完全无关。
sizeof(指针) 返回的是地址本身的存储空间
指针变量本质就是一个存地址的变量,不管它指向什么(int、double、甚至函数),在 64 位系统上都占 8 字节,在 32 位系统上占 4 字节。
立即学习“C++免费学习笔记(深入)”;
常见错误场景:
- 把数组传进函数后用
sizeof想算长度 —— 实际得到的是指针大小,因为形参int arr[]在函数内等价于int* arr - 误以为
sizeof(p)能反映它指向的内存块大小 —— 它只反映p这个变量自己占多少字节
示例:
void f(int arr[]) {
printf("%zu\n", sizeof(arr)); // 输出 8(64 位系统),不是数组原始大小
}
int main() {
int a[10];
f(a); // a 传入时已退化为指针
}为什么数组名在多数地方“像指针”,但在 sizeof 里不是
这是 C/C++ 的语义设计:数组名在表达式中(如 a + 1、*a、赋值给指针)会隐式转换为指向首元素的指针,但这个转换**不发生在 sizeof、& 这些少数几个运算符中**。
关键区别点:
-
sizeof(a)→ 类型是int[N]→ 结果是N * sizeof(int) -
sizeof(&a)→ 类型是int(*)[N](数组指针)→ 结果是指针大小(4 或 8) -
sizeof(p)→ 类型是int*→ 结果始终是指针大小
别指望靠 sizeof 在函数内部还原数组长度 —— 那里已经没“数组”了,只剩一个指针。
容易被忽略的边界情况
真正踩坑的地方往往不在基础用法,而在这些细节:
- 全局数组和局部数组对
sizeof行为一致,但动态分配的内存(如new int[10])返回的是指针,sizeof永远得不到元素个数 -
std::array和std::vector不适用这套规则:std::array支持sizeof得到总大小,但std::vector的sizeof只是对象头大小(通常 24 字节),和容量无关 - 字符串字面量如
"hello"是const char[6]类型,sizeof("hello")是 6,不是 5 —— 别漏掉末尾的\0
记住:sizeof 看的是类型声明那一刻的静态信息,不是运行时内容或指向关系。一旦脱离定义作用域(比如传参、取地址再解引用),数组就大概率“消失”成指针了。


















