部分初始化C结构

bab*_*bon 27 c struct initialization variable-assignment

链接指出"当自动数组或结构具有部分初始化程序时,其余部分初始化为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);
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么4096(我相信这是一些"垃圾"价值)在我评论时打印出来line no. 7,0当我取消评论时我得到了line no. 7.我不认为arr声明与main()激活记录(或更确切myStruct)有关,应该是这样(如果我们没有line no. 7注释):

---------------
|  Saved PC   |
---------------
|  arr[2]     |
---------------
|  arr[1]     |
---------------
|  arr[0]     |
---------------
|  si         |
---------------
|  sj         |
---------------
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下我在这里缺少什么吗?

dbu*_*ush 51

当你这样做:

struct s myStruct;
myStruct.si = 9;
Run Code Online (Sandbox Code Playgroud)

你没有初始化 myStruct.您在没有初始化程序的情况下声明它,然后运行语句来设置一个字段.

因为变量是未初始化的,所以它的内容是未定义的,读取它是未定义的行为.这意味着看似无关的更改可以修改此行为.在您的例子添加一个额外的变量发生导致myStruct.sj为0,但没有保证,这将是这种情况.

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

struct s myStuct = { 9 };
Run Code Online (Sandbox Code Playgroud)

一旦你这样做,那么你将看到myStruct.sj设置为0 的内容.这是根据C标准的 6.7.8部分保证的(突出显示特定于这种情况):

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

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

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

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

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

...

21 如果括号括起的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小的数组的字符串文字中的字符数少于数组中的元素,则聚合的其余部分应与具有静态存储持续时间的对象隐式初始化.

  • @Spotlight这就是OP最初拥有的.他设置了`si`,并认为这是一个初始化,期望`sj`为0. (2认同)

Sou*_*osh 15

在你的情况下,

 myStruct.si = 9;
Run Code Online (Sandbox Code Playgroud)

是一个赋值语句,而不是 初始化.在这种情况下,结构变量(和相应的变量)是未初始化的.因此,您最终会读取未初始化变量的值sj,从而导致 未定义的行为.

你可以试试

struct s myStruct = {9};
Run Code Online (Sandbox Code Playgroud)

在操作中看到隐式初始化.


Que*_*tin 11

这不是初始化程序 - 您的结构未初始化,然后您只分配si.sj仍然没有初始化.

这本书指的是这种代码:

struct s myStruct = {9};
Run Code Online (Sandbox Code Playgroud)

...... sj保证在哪里0.