为什么结构数组不需要大括号初始化?

问题描述

代码

#include <stdio.h>

struct
{
    int i;
    const char* str;
} ar[] = {
    1,"asd",//should be {1,"asd"},2,"qwe",//should be {2,"qwe"},3,"poi" //should be {3,"poi"}
};

int main()
{
    printf("%s\n",ar[2].str);
}

工作得很好,即使数组 ar 的每个元素都应该用大括号括起来(至少我希望如此)。为什么这是可能的?

解决方法

6.7.9 Initialization/20 说明如何初始化此类结构元素:

[..] 如果子聚合或包含联合的初始值设定项开始 带有左大括号,由该大括号括起来的初始值设定项及其 匹配右括号初始化元素或成员 子聚合或包含的联合。否则,就够了 列表中的初始值设定项被考虑到元素或 子聚合的成员或包含的第一个成员 联盟;剩下的初始化器被留下来初始化下一个 当前子聚合的聚合的元素或成员 或包含的联合是一部分。

强调我的

所以它是有效的。于是

ar[] = {
    1,"asd",2,"qwe",3,"poi"
};

相当于:

 ar[] = {
    {1,"asd"},{2,"qwe"},{3,"poi"}
};

ar 包含 3 个元素。

,

这是可能的,原因很简单,标准允许这样做。

那么为什么标准允许它呢?嗯,我不知道这背后是否有任何理由。最可能的原因是这仅仅是因为向后兼容。 C语言充满了这样的东西。

然而,它被认为是不好的风格。所以避免它。如果您在启用警告的情况下编译(您应该这样做),您会收到以下警告:

warning: missing braces around initializer [-Wmissing-braces]
    7 | } ar[] = {
      |          ^
    8 |     1,//should be {1,|     {      }
    9 |     2,//should be {2,|     {       }
   10 |     3,"poi" //should be {3,"poi"}
      |     {
   11 | };
      | }

与许多其他语言相比,C 背后的哲学非常不同。有人可能会争辩说,即使省略大括号是一种糟糕的风格,也没有真正的理由禁止省略它们。例如,它不会引起任何歧义。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...