当使用“传统” ANSI C语言(C89 / 90)的聚合初始化程序({}中的初始化程序)时,必须按顺序从每个结构成员开始为每个结构成员提供单独的初始化程序。 例如
struct S { int a, b, c, d; };
struct S s = { 1, 2, 3, 4 };
/* 1 for `s.a`, 2 for `s.b` and so on... */
您无需为所有成员都指定初始化程序,即可以随时停止(剩余成员将被初始化为零)。
如果由于某种原因您只想显式初始化结构的第三个成员,则必须为第一个和第二个成员提供“虚拟”显式初始化器(只是为了获得所需的第三个)
/* We only care to explicitly initialize `s.c` */
struct S s = { 0, 0, 3 };
/* but we have to explicitly initialize `s.a` and `s.b` as well */
或完全放弃特定的初始化(可能将其替换为通用{}),并使用对特定成员的后续分配
struct S s = { 0 };
s.c = 3;
这种基于分配的方法的显着优势是,它独立于成员2988569802559718718400在声明struct S中的位置。
新的C语言规范(C99)允许您通过在{}中提供所需的成员名称来使用“标记的”初始化程序
struct S s = { .c = 3 };
这样,您只需显式初始化所需的成员(并使编译器对其余成员进行零初始化)。 这不仅为您节省了键入时间,而且使聚合初始化程序独立于结构类型声明中指定成员的顺序。
您可能知道,聚合初始值设定项也可以与数组一起使用。 C99也支持使用数组进行“标记”初始化。 以下示例说明了在数组情况下“标签”的外观
int a[10] = { [5] = 3 };
/* `a[5]` is initialized with 3, the rest of `a` is zero-initialized */
值得一提的是,C语言继续坚持“全有或全无”的方式进行聚合初始化:如果仅为结构或数组的一个(或某些)成员指定显式初始化器,则整个聚合将 初始化,并且没有显式初始化程序的成员将被零初始化。