C 嵌套大括号和指定的初始值设定项

C 嵌套大括号和指定的初始值设定项,c,C,为什么我需要嵌套的大括号来编译这段代码 #include <stdio.h> #include <stdlib.h> typedef union TEST TEST; union TEST { int type; char *things; }; int main () { TEST test[] = {1, 2, .things = NULL}; // Compile time error TEST test[] = {1,

为什么我需要嵌套的大括号来编译这段代码

#include <stdio.h>
#include <stdlib.h>

typedef union TEST TEST;

union TEST {
    int type;
    char *things;
 };


int main () {

    TEST test[] = {1, 2, .things = NULL}; // Compile time error

    TEST test[] = {1, 2, {.things = NULL}}; // Works, but I didn't check at run time

    return 0;
}
#包括
#包括
联合试验;
联合试验{
int型;
事物;
};
int main(){
TEST TEST[]={1,2,.things=NULL};//编译时错误
testtest[]={1,2,{.things=NULL};//有效,但我在运行时没有检查
返回0;
}
为什么第一个作业不起作用?
为什么需要内支架?
在第一次任务中有什么方法可以工作吗?没有内支架


谢谢大家!

在初始值设定项列表的语法中,前两个元素不需要内部大括号这一事实是一个奇怪的细节,它允许将联合初始化为其第一个元素。我建议对列表中的所有初始值设定项使用大括号和名称,而不仅仅是
。things

在初始值设定项列表的语法中,前两个元素不需要内部大括号这一事实是一个奇怪的细节,它允许将联合初始化为其第一个元素。我建议对列表中的所有初始值设定项使用大括号和名称,而不仅仅是
.things

总之:
{1,2,.things=NULL}
尝试初始化数组
test
中名为
things
的元素,但数组中没有名为
things
的元素,所以这是无效的。相反,
{1,2,{.things=NULL}
尝试初始化数组中名为
things
的第二个元素的成员,而数组的第二个元素是一个联合,它确实有一个名为
things
的成员,因此这是有效的

根据C 2011(N1570)6.7.9 17:

每个括号内的初始值设定项列表都有一个关联的当前对象。当不存在指定时,将根据当前对象的类型依次初始化当前对象的子对象:按递增下标顺序的数组元素、按声明顺序的结构成员以及联合的第一个命名成员。相反,指定会导致以下初始值设定项开始初始化该指定项所描述的子对象。然后,初始化继续按顺序向前,从指示器描述的子对象之后的下一个子对象开始

在后面的段落中有更多关于如何处理当前对象的内容,但这就足够了。在括号内的初始值设定项列表中,
1
是一个简单的初始值设定项;它没有任何名称。因此它初始化数组的一个子对象,即数组元素。类似地,
2
初始化另一个元素。然后我们有
。things=NULL
。它确实有一个指示符,
。things

根据引用的段落,此指示符,
.things
导致初始化由
.things
描述的子对象。但是数组中没有由
.things
指定的内容。它只是一个包含索引元素的数组,由
[index]
指定。它没有任何由
.thigns
指定的成员。所以有一个错误

在第二个列表中,如果使用了其他大括号,则第20段适用:

如果集合或联合包含属于集合或联合的元素或成员,则这些规则将递归应用于子集合或包含的联合。如果子集合或包含的并集的初始值设定项以左大括号开头,则由该大括号及其匹配的右大括号括起的初始值设定项将初始化子集合或包含的并集的元素或成员


在本例中,
{.things=NULL}
以左大括号开始。这表示大括号中包含的初始值设定项初始化较大列表的当前对象。因此,他们正在初始化数组的下一个元素(索引为2的元素)。数组的任何元素都是一个名为
things
的成员的并集,因此
things
确实在其中指定了一个子对象,并且这种语法是可以接受的。

总之:
{1,2,.things=NULL}
尝试初始化名为
things
的数组
test
的元素,但是数组没有名为
things
的元素,因此这是无效的。相反,
{1,2,{.things=NULL}
尝试初始化数组中名为
things
的第二个元素的成员,而数组的第二个元素是一个联合,它确实有一个名为
things
的成员,因此这是有效的

根据C 2011(N1570)6.7.9 17:

每个括号内的初始值设定项列表都有一个关联的当前对象。当不存在指定时,将根据当前对象的类型依次初始化当前对象的子对象:按递增下标顺序的数组元素、按声明顺序的结构成员以及联合的第一个命名成员。相反,指定会导致以下初始值设定项开始初始化该指定项所描述的子对象。然后,初始化继续按顺序向前,从指示器描述的子对象之后的下一个子对象开始

在后面的段落中有更多关于如何处理当前对象的内容,但这就足够了。在括号内的初始值设定项列表中,
1
是一个简单的初始值设定项;它没有任何名称。因此它初始化数组的一个子对象,即数组元素。类似地,
2
初始化另一个元素。然后我们有
。things=NULL
。它确实有一个指示符,
。things

根据引用的段落,此指示符,
.things
导致初始化由
.things
描述的子对象。但是数组中没有由
.things
指定的内容。它只是一个包含索引元素的数组,由
[index]
指定。它没有任何m