简体   繁体   English

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

[英]Initialization array of structs - {NULL} vs {}

If I have this struct: 如果我有这个结构:

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

What would be the difference between following initialization: 以下初始化之间有什么区别:

option 1: 选项1:

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

option 2: 选项2:

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

The first version is immediately illegal. 第一个版本立即是非法的。 C language does not support {} initializers. C语言不支持{}初始化程序。

The second version is generally illegal, even though it might "compile" in some implementations. 第二个版本通常是非法的,即使它在某些实现中可能会“编译”。 In this case, in accordance with the rules of aggregate initialization your NULL will act as an initializer for someObjects[0].type1 field. 在这种情况下,根据聚合初始化规则,您的NULL将充当someObjects[0].type1字段的初始化程序。 This field has type int . 此字段的类型为int However, even though in many implementations you might be able to successfully initialize int objects with NULL , in general case it is not possible. 但是,即使在许多实现中,您都可以使用NULL成功初始化int对象,但通常情况下是不可能的。 NULL is intended to be used in pointer context, not in integer context. NULL旨在用于指针上下文,而不是整数上下文。

If you want to zero-initialize your entire array, the proper way to do it is 如果要对整个数组进行零初始化,则正确的方法是

MyStruct someObjects[5] = { 0 };

MyStruct someObjects[5] = {}; isn't conformant C and whether MyStruct someObjects[5] = {NULL}; 是否符合C,以及MyStruct someObjects[5] = {NULL};是否MyStruct someObjects[5] = {NULL}; is conformant C is implementation defined*. 符合C是实现定义的*。

You should initialize it with MyStruct someObjects[5] = {0}; 您应该使用MyStruct someObjects[5] = {0};初始化它MyStruct someObjects[5] = {0}; . {0} is the way to default/zero-initialize any array, aggregate object or compound literal in C. {0}是对C中的任何数组,聚合对象或复合文字进行默认/零初始化的方法。

{0} works for default/zero-initialization because 6.7.9p19 and 6.7.9p20 will cause the 0 to recursively target the first primitive object, because every primitive data object in C is either numerical or a pointer and therefore initialiazable with 0 and finally because 6.7.9p21 says that: {0}适用于默认/零初始化,因为6.7.9p196.7.9p20将导致0递归地定位第一个原始对象,因为C中的每个原始数据对象都是数字或指针,因此可以用0初始化,最后因为6.7.9p21表示:

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration. 如果用大括号括起来的列表中的初始化程序少于聚合中的元素或成员,或者用于初始化已知大小的数组的字符串文字中的字符少于该数组中的元素,则聚合的其余部分应与具有静态存储持续时间的对象一样隐式初始化。


* NULL could be defined as 0 in which case {NULL} is OK, or it could just as well be defined (void*)0 in which case {NULL} 's not OK in your case because recursively, you're array's first primitive object ( int type1; ) is not a pointer initalizable from (void*) or even a pointer. * NULL可以定义为0在这种情况下{NULL}是可以的,或者也可以定义为(void*)0在这种情况下, {NULL}不能满足您的要求,因为递归地,您是数组的第一个原始对象( int type1; )不能从(void*)初始化,甚至不是指针。

The difference is that the first is illegal in standard C, and the second may or may not be. 区别在于,第一个在标准C中是非法的,第二个可能是也可能不是。

{} in an initializer is not legal in C; 初始化器中的{}在C语言中不合法; you need at least one element between the { and } . {}之间至少需要一个元素。 (Some compilers might permit it as an extension; I think gcc does.) (某些编译器可能允许它作为扩展;我认为gcc可以。)

A common idiom is 一个常见的成语是

some_type blah[] = { 0 };

The initial element is initialized to 0 (which could be a null pointer, floating-point zero, a null character, etc.), and the remaining unspecified elements are initialized to zero for the appropriate type. 初始元素被初始化为0 (可以是空指针,浮点数为零,空字符等),而其余未指定的元素被初始化为零以适用于类型。

With the {NULL} initializer you're trying to initialize someObjects[0].type1 , an int to NULL . 随着{NULL}初始化你想初始化someObjects[0].type1 ,一个intNULL The NULL macro is intended to be used as a null pointer constant. NULL宏旨在用作空指针常量。 It may or may not be defined as a constant 0 , so the legality of your initializer is implementation-specific. 可能会或可能不会定义为常数0 ,因此初始化器的合法性是特定于实现的。

Just write 写吧

MyStruct someObjects[5] = {0};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM