部分初始化C结构

时间:2016-05-31 14:19:50

标签: c struct initialization variable-assignment

link表示"当自动数组或结构具有部分初始值设定项时,余数初始化为0"。我决定尝试我读到的内容并编写以下代码:

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

int main(void)
{
    //int arr[3] = {2};  // line no. 7

    struct s {
        int si;
        int sj;
    };

    struct s myStruct;
    myStruct.si = 9;
    printf("%d\n", myStruct.sj);
}

我不明白为什么4096(我相信是某些&#34;垃圾&#34;值)在我发表评论line no. 7时会打印出来0当我取消注释line no. 7时。我不认为arr声明与main()的激活记录(或更确切地说myStruct)有关,应该是这样的(如果我们有{ {1}}取消评论):

line no. 7

有人可以解释我在这里缺少的东西吗?

4 个答案:

答案 0 :(得分:51)

执行此操作时:

struct s myStruct;
myStruct.si = 9;

您尚未初始化 myStruct。您在没有初始化程序的情况下将其声明为,然后运行语句以设置一个字段。

因为变量未初始化,其内容未定义,读取内容为undefined behavior。这意味着看似无关的更改可以修改此行为。在您的示例中添加了一个额外的变量发生以使myStruct.sj为0,但不保证会出现这种情况。

初始化变量,您必须在定义时为其赋值:

struct s myStuct = { 9 };

如果你这样做,那么你会看到myStruct.sj的内容设置为0.这是根据the C standard的第6.7.8节保证的(具体针对这种情况突出显示) :

  

10如果没有自动存储持续时间的对象   显式初始化,其值是不确定的。 如果是对象   具有静态存储持续时间的未初始化   显式,然后:

     

- 如果它有指针类型,则将其初始化为null   指针;

     

- 如果它有算术类型,则将其初始化为(正数或   无符号)零;

     

- 如果是聚合,则会初始化每个成员   (递归地)根据这些规则;

     

- 如果它是一个联盟,第一个   命名成员根据这些规则初始化(递归)。

     

...

     

21 如果括号括起的列表中的初始值设定项少于此值   是聚合的元素或成员,或者是一个或更少的字符   string literal用于初始化已知大小的数组   是数组中的元素,聚合的其余部分   应该与具有静态的对象隐式初始化   储存期限。

答案 1 :(得分:15)

在你的情况下,

 myStruct.si = 9;

assignment 声明,不是 initialization 。在这种情况下,结构变量(和相应的变量)是未初始化的。因此,您最终会读取未初始化变量sj的值,从而导致undefined behavior

你可以尝试

struct s myStruct = {9};

查看隐式初始化

答案 2 :(得分:11)

这不是初始化程序 - 您的结构未初始化,然后您只分配sisj仍未初始化。

这本书指的是这种代码:

struct s myStruct = {9};

...其中sj保证为0。

答案 3 :(得分:2)

这基本上是一个 - 或多或少完整的例子,用于其他人已经给出的伟大答案。

#include<stdio.h>

struct{
  int a;
  int b;
}obj1={.a=0}; //Partial initialization

typedef struct struct_B{
  int a;
  int b;
}struct_B;

int main(void)
{
  printf("obj1.b : %d\n",obj1.b);
  struct_B obj2={.b=1,.a=0,0}; // b's first value is overridden here as 0 immediately follows a
  printf("obj2.b : %d\n",obj2.b);
  struct_B obj3={0}; //Partial initialization, here the '0' value is meant for a as it comes first in the declaration
  printf("obj3.b : %d\n",obj3.b);
  struct_B obj4={.a=0}; //Partial initialization
  printf("obj4.b : %d\n",obj4.b);
  return 0;
}

<强>输出:

obj1.b : 0
obj2.b : 0
obj3.b : 0
obj4.b : 0