我知道在C99中你可以使用成员名称初始化结构的成员,如下所示:
struct myStruct
{
int i;
char c;
float f;
};
以下是有效的:
struct myStruct m = {.f = 10.11, .i = 5, .c = 'a'};
还有人说未初始化的成员将被设置为0
。所以
struct myStruct m = {.f = 10.11, .c = 'a'};
此处i
将设置为0
但是,对于以下内容:
struct myStruct m = {.f = 10.11, .c = 'a', 6};
i
仍然初始化为0.如果我们进行这样的复合初始化,原因是什么。
答案 0 :(得分:14)
这在C99标准部分6.7.8
初始化草案中有所涉及,基本上如果以下初始化程序不是指示符,那么它将在该指定符之后接收下一个字段,你的例子是f
。我们可以看一下 17 的段落(强调我的):
每个大括号括起的初始化列表都有一个关联的当前对象。 当没有指定时,当前对象的子对象是 根据当前对象的类型按顺序初始化: 数组元素增加下标顺序,结构成员在 声明顺序,以及union的第一个指定成员.29)In 对比度,指定会导致以下初始值设定项开始 初始化由指示符描述的子对象。 然后初始化按顺序继续向前,从 在指定者描述之后的下一个子对象 .130)
为什么i
被初始化为0
的内容已在paragrah 19 中说明:
初始化应在初始化程序列表顺序中进行 初始化程序为特定的子对象提供覆盖任何子对象 以前列出的同一子对象的初始值设定项; 132)全部 未明确初始化的子对象应初始化 隐式与具有静态存储持续时间的对象相同。
请注意,正如Keith指出gcc
使用-Wextra
为此提供了警告:
warning: initialized field overwritten [-Woverride-init]
struct myStruct m = {.f = 10.11, .c = 'a', 6};
^
和clang
似乎默认警告这一点。
答案 1 :(得分:6)
如果是
struct myStruct = {.f = 10.11, .c = 'a', 6};
非指定初始化程序的值6
将在使用指定的初始化程序初始化成员之后分配给成员。因此,在这种情况下,成员f
就在c
之后,因此它将初始化为6
。 <{1}}默认情况下仍会初始化为i
。
答案 2 :(得分:0)
这里,6是非指定的初始化器。因此,此值初始化为刚刚在前一个指定的初始值设定项之后的成员,即在char之后的浮点数。
如果您有两个或多个非指定的初始值设定项,那么非指定的初始值设定项将从最后指定的初始化程序初始化为系列成员。