结构的初始化数组-{NULL}与{}

时间:2018-11-14 23:12:17

标签: c arrays struct

如果我有这个结构:

typedef struct MyStruct
{
    int type1;
    char *type2;
    char type3[CHARS_AMOUNT];
} MyStruct;

以下初始化之间有什么区别:

选项1:

int main(int argc, char *argv[])
{
    MyStruct someObjects[5] = {};
}

选项2:

int main(int argc, char *argv[])
{
    MyStruct someObjects[5] = {NULL};
}

3 个答案:

答案 0 :(得分:2)

第一个版本立即是非法的。 C语言不支持{}初始化程序。

第二个版本通常是非法的,即使它在某些实现中可能会“编译”。在这种情况下,根据聚合初始化规则,您的NULL将充当someObjects[0].type1字段的初始化程序。该字段的类型为int。但是,即使在许多实现中,您都可以使用int成功初始化NULL对象,但通常是不可能的。 NULL旨在用于指针上下文,而不是整数上下文。

如果要对整个数组进行零初始化,则正确的方法是

MyStruct someObjects[5] = { 0 };

答案 1 :(得分:2)

MyStruct someObjects[5] = {};不是C且 MyStruct someObjects[5] = {NULL};是否符合C由实现定义*。

您应使用MyStruct someObjects[5] = {0};对其进行初始化。 {0}是对C中的任何数组,聚合对象或复合文字进行默认/零初始化的方法。

{0}适用于默认/零初始化,因为6.7.9p196.7.9p20将导致0递归地定位第一个原始对象,因为C中的每个原始数据对象是数字或指针,因此可以用0初始化,最后是因为6.7.9p21表示:

  

如果用大括号括起来的列表中的初始化程序少于那里   是集合中的元素或成员,或者   字符串文字,用来初始化一个已知大小的数组   是数组中的元素,聚合的其余部分应为   隐式初始化为与具有静态存储的对象相同   持续时间。


在这种情况下NULL可以将

* 0定义为{NULL},或者在这种情况下也可以将其定义为(void*)0 {NULL}在您的情况下不适合,因为递归地,您不是数组的第一个原始对象(int type1;)不能从(void*)甚至指针都不能初始化指针。

答案 2 :(得分:2)

区别在于第一个在标准C中是非法的,第二个可能是也可能不是。

{}在C语言中不合法;您需要在{}之间至少包含一个元素。 (某些编译器可能会允许它作为扩展;我认为gcc可以。)

一个常见的成语是

some_type blah[] = { 0 };

初始元素被初始化为0(可以是空指针,浮点零,空字符等),而对于适当的类型,其余未指定的元素被初始化为零。 / p>

使用{NULL}初始化程序,您尝试初始化someObjects[0].type1int的{​​{1}}。 NULL宏旨在用作空指针常量。它可以可以或可以定义为常量NULL,因此初始化程序的合法性是特定于实现的。

只要写

0