当您使用聚合初始值设定项时(中的初始值设定项{}
)在“传统”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 */
或完全放弃特定的初始化(可能用通用的替换它)= { 0 }
) 并使用后续分配给特定成员
struct S s = { 0 };
s.c = 3;
这种基于任务的方法的一个显着好处是它独立于成员的职位c
在声明中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 语言再次坚持“全有或全无”的聚合初始化方法:如果您为结构体或数组的一个(或某些)成员指定显式初始化程序,则整个聚合将得到初始化,并且没有显式初始化器的成员被零初始化。