c++数组长度必须编译期确定,仅允许字面量、constexpr变量或宏;初始化时可省略长度由编译器推导;局部未初始化数组含垃圾值;数组名非指针但常退化为指针。

数组声明必须用常量表达式指定长度
你不能写 int arr[n];(其中 n 是普通变量),编译器会报错:「error: variable-sized object may not be initialized」或类似提示。C++ 标准要求数组大小在编译期就能确定,所以只接受字面量、constexpr 变量、宏定义等。
常见合法写法:
int arr[10];constexpr int size = 5; int arr[size];#define SIZE 8<br>int arr[SIZE];
错误写法示例:int n = 7; int arr[n]; —— 这在 C++ 中非法(尽管某些编译器用扩展支持,但不可移植)。
初始化时省略长度是安全且推荐的
当你在声明时提供初始化列表,编译器能自动推导长度,这种写法既简洁又避免手误出错。例如:int arr[] = {1, 2, 3}; 等价于 int arr[3] = {1, 2, 3};。
注意两点:
- 这种推导只发生在声明+初始化同时进行时;单独写
int arr[];是非法的 - 如果初始化列表为空(如
int arr[] = {};),C++11 起允许,但长度为 0 —— 多数场景下无意义,且不能取地址或做指针运算
局部数组不初始化就是垃圾值
函数内声明的数组(比如 void foo() { int buf[1024]; })若未显式初始化,所有元素值是未定义的,可能是任意二进制内容。读取它们会导致未定义行为(UB),不是「0」也不是「null」。
要确保清零,有几种可靠方式:
int buf[1024] = {}; // C++11 起推荐,全部设为 0int buf[1024] = {0}; // 兼容老标准,首元素为 0,其余自动补 0int buf[1024]{ }; // 统一初始化语法,效果同上
别依赖「没写初始化就默认是 0」——那只对 static 或全局数组成立。
数组名不是指针,但常退化为指针
sizeof(arr) 在数组作用域内返回的是总字节数(如 int arr[5]; sizeof(arr) 是 20),这说明 arr 本身是个类型为「5 个 int 的数组」的实体。但一旦传入函数、参与算术运算或取地址,它就会隐式转换成指向首元素的指针(int*)。
这个退化是很多 bug 的源头:
- 函数参数写
void func(int arr[])实际等价于void func(int* arr),sizeof(arr)在函数内永远是指针大小(通常是 8) -
&arr + 1和arr + 1地址差不同:前者跳过整个数组,后者只跳过一个元素
真正需要保留大小信息时,优先用 std::array 或传递长度参数,别只靠数组名。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











