部分初始化C结构

部分初始化C结构,c,struct,initialization,variable-assignment,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; };

这表示“当自动数组或结构具有部分初始值设定项时,其余部分将初始化为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);
}
有人能解释一下我遗漏了什么吗?

就你而言

 myStruct.si = 9;
是一个语句,不是。在这种情况下,结构变量(以及相应的变量)未初始化。因此,您将读取未初始化变量的值
sj
,这将导致错误

你可以试试

struct s myStruct = {9};
要查看隐式初始化的操作。

执行此操作时:

struct s myStruct;
myStruct.si = 9;
您没有初始化myStruct。在没有初始值设定项的情况下声明它,然后运行语句来设置一个字段

因为变量未初始化,所以它的内容未定义,读取它也是如此。这意味着看似无关的更改可以修改此行为。在您的示例中,添加一个额外的变量碰巧导致
myStruct.sj
为0,但不能保证会出现这种情况

要初始化变量,必须在定义变量时为其指定一个值:

执行此操作后,您将看到
myStruct.sj
的内容设置为0。这是根据第6.7.8节保证的(针对这种情况突出显示):

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

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

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

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

-如果是工会,第一个 命名成员根据这些规则进行初始化(递归)

21如果括号内的列表中的初始值设定项少于 是聚合的元素或成员,或在聚合中少于个字符 用于初始化已知大小的数组的字符串文字 是数组中的元素,聚合的剩余部分 应隐式初始化为与具有静态 存储时间。


这不是初始值设定项--您的结构未初始化,然后只分配
si
<代码>sj保持未初始化状态

本书所指的是此类代码:

struct s myStruct = {9};

。。。其中,
sj
保证为0。

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

#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;
}

相关:
在不使用初始值设定项的情况下声明它
是一种很好的表达方式。。作为旁注,没有一个答案解释了
I在取消注释第7行时得到0
编译器选项可以设置为将所有内存初始化为零,一些操作系统可以这样做,但是
myStruct.sj
可以是@dbush指出的任何东西。如果
myStruct.sj
是一个指针,那么未初始化的值可能会导致各种各样的问题,这种情况在我身上发生过。@MichaelShopsin:如果未设置compliler选项,您能给
一些这样做的操作系统举个例子吗。我相信Linux和Windows都不会这么做。关于“当我取消注释第7行时,我得到了0”:正如dbush所指出的(“看似不相关的更改……添加一个额外的变量碰巧导致myStruct.sj为0”),根据定义,它是未定义的,在合理的实践中,不管发生什么事情,它都会留在内存中。如果要改变
arr[3]
定义的大小(从而改变内存映射中
si
sj
的内存深度),可能会得到整个范围的值。@Spotlight这就是OP最初的功能。他设置了
si
,并认为这是一个初始化,期望
sj
为0。
struct s myStruct = {9};
#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