如何根据C编程语言标准初始化结构

How to initialize a struct in accordance with C programming language standards

我想初始化一个结构元素,在声明和初始化中拆分。这就是我所拥有的:

1
2
3
4
5
6
7
8
9
10
11
typedef struct MY_TYPE {
  bool flag;
  short int value;
  double stuff;
} MY_TYPE;

void function(void) {
  MY_TYPE a;
  ...
  a = { true, 15, 0.123 }
}

这是根据C编程语言标准(C89、C90、C99、C11等)声明和初始化MY_TYPE的局部变量的方法吗?或者有什么更好的或者至少是有效的吗?

更新最终得到了一个静态初始化元素,在该元素中,我根据需要设置每个子元素。


在(ansi)c99中,可以使用指定的初始值设定项初始化结构:

1
MY_TYPE a = { .flag = true, .value = 123, .stuff = 0.456 };

编辑:其他成员初始化为零:"省略的字段成员隐式初始化与具有静态存储持续时间的对象相同。"(https://gcc.gnu.org/onlinedocs/gcc/designated-inits.html)


你可以用复合文字来完成。根据那个页面,它在C99中工作(也算是ANSI C)。

1
2
3
4
5
MY_TYPE a;

a = (MY_TYPE) { .flag = true, .value = 123, .stuff = 0.456 };
...
a = (MY_TYPE) { .value = 234, .stuff = 1.234, .flag = false };

初始值设定项中的指定是可选的;您还可以编写:

1
2
3
a = (MY_TYPE) { true,  123, 0.456 };
...
a = (MY_TYPE) { false, 234, 1.234 };


我知道你已经收到了一个关于ANSIC 99的答案,所以我要对ANSIC 89做一个总结。ANSIC 89允许您通过以下方式初始化结构:

1
2
3
4
5
6
7
8
9
10
typedef struct Item {
    int a;
    float b;
    char* name;
} Item;

int main(void) {
    Item item = { 5, 2.2,"George" };
    return 0;
}

需要记住的一点是,在初始化结构中的一个对象/变量时,它的所有其他变量都将被初始化为默认值。

如果不初始化结构中的值,则所有变量都将包含"垃圾值"。

祝你好运!


a = (MYTYPE){ true, 15, 0.123 };

在C99里可以


你已经差不多了…

1
MY_TYPE a = { true,15,0.123 };

"struct initialize c"上的快速搜索显示


C programming language standard ISO/IEC 9899:1999 (commonly known as C99) allows one to use a designated initializer to initialize members of a structure or union as follows:

1
MY_TYPE a = { .stuff = 0.456, .flag = true, .value = 123 };

它在ISO/IEC 9899:1999标准的paragraph 7节第6.7.8 Initialization节中定义为:

If a designator has the form
. identifier
then the current object (defined below) shall have structure or union type and the identifier shall be the name of a member of that type.

请注意,同一章节的paragraph 9指出:

Except where explicitly stated otherwise, for the purposes of this subclause unnamed members of objects of structure and union type do not participate in initialization. Unnamed members of structure objects have indeterminate value even after initialization.

然而,在GNUGCC实现中,省略的成员被初始化为类似于零或零的类型适当的值。如GNU GCC文件第6.27节指定初始值设定项所述:

Omitted field members are implicitly initialized the same as objects that have static storage duration.

微软Visual C++编译器应该支持指定的初始化器,因为版本2013根据官方博客后C++一致性路线图。msdn-visual studio文档中初始值设定项文章的Initializing unions and structs段表明,未命名成员初始化为零类似于GNUgcc的适当值。

取代了ISO/IEC 9899:1999的ISO/IEC 9899:2011标准(通常称为C11)保留了6.7.9 Initialization节下的指定初始值设定项。它还保持了paragraph 9不变。

取代了ISO/IEC 9899:2011的新ISO/IEC 9899:2018标准(通常称为C18)保留了6.7.9 Initialization节下的指定初始值设定项。它还保持了paragraph 9不变。


正如罗恩·努尼所说:

1
2
3
4
5
6
7
8
9
10
typedef struct Item {
    int a;
    float b;
    char* name;
} Item;

int main(void) {
    Item item = {5, 2.2,"George"};
    return 0;
}

需要记住的一件重要事情是:即使在结构中初始化了一个对象/变量,它的所有其他变量都将被初始化为默认值。

如果不初始化结构中的值(即,如果只声明该变量),则所有variable.members都将包含"垃圾值",前提是声明是本地的!

如果声明是全局的或静态的(在本例中类似),则所有未初始化的variable.members将自动初始化为:

  • 整数和浮点的0
  • '\0'表示char(当然这和0是一样的,char是整数型)
  • 用于指针的NULL


1
2
3
4
5
6
void function(void) {
  MY_TYPE a;
  a.flag = true;
  a.value = 15;
  a.stuff = 0.123;
}


我找到了另一种初始化结构的方法。

结构:

1
2
3
4
typedef struct test {
    int num;
    char* str;
} test;

初始化:

1
2
3
4
test tt = {
    num: 42,
    str:"nice"
};

根据GCC的文档,该语法自GCC 2.5以来已过时。


如果MS没有更新到C99,我的类型A=真,15,0.123


我不喜欢这些答案,所以我自己做了。我不知道这是不是ANSI C,它只是GCC4.2.1的默认模式。我永远记不起括号,所以我从我的数据的一个子集开始,并与编译器错误消息作斗争,直到它关闭为止。可读性是我的首要任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    // in a header:
    typedef unsigned char uchar;

    struct fields {
      uchar num;
      uchar lbl[35];
    };

    // in an actual c file (I have 2 in this case)
    struct fields labels[] = {
      {0,"Package
<div class="
suo-content">[collapse title=""]<ul><li>对于结构数组的初始化是毫无疑问的!我的意思是,你的答案包含开销。</li><li>我想我的观点是用已经存在的值声明结构,而不是使用=稍后设置每个值。</li><li>无论是一个结构还是它们的数组,这一原则都适用。我不认为使用=不是真正的初始化。</li></ul>[/collapse]</div><p><center>[wp_ad_camp_3]</center></p><hr><P>我已经阅读了有关初始化聚合类型的Microsoft Visual Studio 2015文档,这里解释了使用<wyn>{...}</wyn>初始化的所有形式,但是这里没有提到用点初始化,即"指示符"。它也不起作用。</P><P>C99标准第6.7.8章"初始化"解释了指示器的可能性,但在我看来,对于复杂的结构来说还不太清楚。C99标准为PDF格式。</P><P>在我看来,最好是</P><li>对所有静态数据使用<wyn>= {0};</wyn>初始化。这对于机器代码来说是比较简单的。</li><li><P>例如,使用宏初始化</P><P><wyn>typedef MyStruct_t{ int x, int a, int b; } MyStruct;
define INIT_MyStruct(A,B) { 0, A, B}</wyn></P></li><P>宏可以调整,其参数列表可以独立于更改的结构内容。如果初始化的元素较少,则是正确的。它也适用于嵌套结构。三。一个简单的形式是:在子程序中初始化:</P>[cc lang="
c"]void init_MyStruct(MyStruct* thiz, int a, int b) {
  thiz->a = a; thiz->b = b; }

这个例程看起来像在C中面向对象,使用EDCOX1,3,而不是EDCOX1,4,用C++编译它!

1
2
MyStruct data = {0}; //all is zero!
init_MyStruct(&data, 3, 456);

C中的结构可以这样声明和初始化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef struct book
{
    char title[10];
    char author[10];
    float price;
} book;

int main() {
    book b1={"DS","Ajay", 250.0};

    printf("%s \t %s \t %f", b1.title, b1.author, b1.price);

    return 0;
}

我一直在寻找一种初始化结构的好方法,我必须使用下面的(c99)。这允许我以与普通类型相同的方式初始化单个结构或结构数组。

1
2
3
4
5
6
7
8
typedef struct {
    char *str;
    size_t len;
    jsmntok_t *tok;
    int tsz;
} jsmn_ts;

#define jsmn_ts_default (jsmn_ts){NULL, 0, NULL, 0}

这在代码中可用作:

1
2
3
4
jsmn_ts mydata = jsmn_ts_default; /* initialization of a single struct */

jsmn_ts myarray[10] = {jsmn_ts_default, jsmn_ts_default}; /* initialization of
                                                    first 2 structs in the array */