静态一维数组大小必须在编译期确定,仅允许字面量、constexpr变量或模板参数;运行时大小须用std::vector或new;std::array更安全但语法稍重,C风格数组易退化为指针且无边界检查。

静态一维数组必须在编译期确定大小
你不能用变量、函数返回值或用户输入来指定 std::array 或 C 风格数组的长度。比如 int n = 5; int arr[n]; 在标准 C++ 中是非法的(即使某些编译器允许,也属于 VLAs 扩展,不可移植)。
- 合法写法只有:字面量(
int arr[10];)、constexpr变量(constexpr int N = 10; int arr[N];)、模板参数(template<int n> void f() { int a[N]; }</int>) - 如果大小来自运行时,必须用
std::vector或new int[n](后者需手动delete[]) - 常见错误现象:
error: variable length array declaration not allowed in C++
std::array 比 C 风格数组更安全但语法稍重
std::array 是栈上分配、大小固定、支持范围访问和迭代器的标准容器;C 风格数组(T arr[N])更轻量但容易退化为指针、无边界检查。
- 初始化方式不同:
std::array<int> a = {1,2,3};</int>必须显式写出大小;而int a[] = {1,2,3};可省略大小,但这是 C 风格且不推荐用于函数参数传递 - 传参陷阱:C 风格数组作为函数参数会自动退化为指针,丢失长度信息;
std::array传值或传引用都能保留尺寸 - 性能差异极小,但
std::array的at()方法提供运行时越界检查(可选),operator[]和 C 风格一样不检查
全局/静态作用域下的数组初始化规则更严格
在文件作用域或 static 局部变量中定义数组时,若未显式初始化,整型元素会被零初始化(不是未定义值),这点和局部栈变量不同。
- 例如:
static int a[3];等价于static int a[3] = {0};;而int a[3];在函数内则内容是未定义的 - 使用
{}初始化会触发聚合初始化:未指定的元素补零,如int a[5] = {1};→{1,0,0,0,0} - 注意:
std::array在静态存储期下也会零初始化其内部 C 数组,行为一致
不要在头文件里定义非 inline 的静态数组
如果你在头文件中写了 static int arr[10]; 或 int arr[10];(没有 extern),每个包含它的 .cpp 文件都会生成一份副本,链接时报 multiple definition 错误。
立即学习“C++免费学习笔记(深入)”;
- 正确做法:头文件中声明为
extern int arr[10];,在某个 .cpp 中定义int arr[10]; - 或者改用
inline constexpr std::array(C++17 起):inline constexpr std::array<int> arr = {1,2,3};</int>,可安全放在头文件中 - 常见错误信息:
multiple definition of 'arr',尤其在启用多个 TU 编译时突然出现











