{}初始化数组时触发聚合初始化,要求类型为聚合体;int a[5]{}和int a[5]{0}均使所有元素为0,但前者为值初始化(零初始化),后者为列表初始化(首元素赋值、其余零初始化),且{}禁止窄化转换。

用 {} 初始化数组时,编译器到底在做什么
它不是简单地“把值塞进去”,而是触发了聚合初始化(aggregate initialization),要求类型是聚合体(比如内置数组、struct、class 无用户定义构造函数等)。对 int arr[3] = {1, 2, 3}; 这种写法,{} 是语法糖,本质仍是传统初始化;但换成 int arr[3]{1, 2, 3};(省略 =),就明确启用列表初始化语义,此时会做更严格的类型检查和零初始化兜底。
int a[5]{}; 和 int a[5]{0}; 效果一样吗
效果相同:两者都让所有元素为 0。但原理不同:{} 触发值初始化(value-initialization),对内置类型即零初始化;{0} 是带一个元素的初始化列表,剩余元素自动零初始化。关键差异在于容错性:
-
int a[3]{1};→a[0]=1,a[1]=0,a[2]=0 -
int a[3]{1, 2};→a[0]=1,a[1]=2,a[2]=0 -
int a[3]{1, 2, 3, 4};→ 编译错误:too many initializers for 'int [3]' -
int a[3]{1.5};→ 编译错误:cannot convert 'double' to 'int' in initialization(列表初始化禁止窄化转换)
std::array 怎么用 {} 初始化才不踩坑
std::array 是聚合体,支持 {} 初始化,但括号层级容易出错。常见误写:std::array<int> a{1, 2, 3};</int> 看似合理,实际依赖聚合初始化规则——它等价于按成员顺序初始化(即直接初始化其内部 C 风格数组),所以能工作;但更清晰、更安全的写法是加一层大括号:
std::array<int, 3> a{{1, 2, 3}}; // C++11/14 写法,外层是 std::array 构造,内层是其内部数组初始化
C++17 起支持类模板参数推导,可简写为:
立即学习“C++免费学习笔记(深入)”;
auto a = std::array{1, 2, 3}; // 推导为 std::array<int, 3>
注意:std::array<int, 3> a{1, 2}; 合法(未指定的元素零初始化),但 std::array<int, 3> a{1, 2, 3, 4}; 编译失败。
char 数组用 {} 初始化字符串要小心什么
写 char s[10]{"hello"}; 没问题,但写 char s[10]{"hello world"}; 就越界了("hello world" 共 12 字符含 \0)。而用 {} 显式初始化时,若长度不足且未显式补 \0,后果不确定:
-
char s[6]{"hello"};→ 安全,s[5]自动为\0 -
char s[6]{'h','e','l','l','o'};→s[5]是未定义值(非\0) -
char s[6]{};→ 全部为\0,安全
字符串字面量初始化天然带终止符,但逐字符 {} 列表不自动补,这点常被忽略。


















