部分初始化 C 结构
Partially initializing a C struct
此 link 表示 "When an automatic array or structure has a partial initializer, the remainder is initialized to 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);
}
我不明白为什么当我注释掉 line no. 7
时打印 4096
(我相信它是一些 "garbage" 值),而当我取消注释 line no. 7
。我认为 arr
声明与 main()
的激活记录(或者更确切地说 myStruct
)没有任何关系,它应该看起来像(假设我们有 line no. 7
未注释):
---------------
| Saved PC |
---------------
| arr[2] |
---------------
| arr[1] |
---------------
| arr[0] |
---------------
| si |
---------------
| sj |
---------------
有人可以解释一下我在这里缺少什么吗?
在你的情况下,
myStruct.si = 9;
是一个assignment statement, not initialization. In this case, the structure variable (and the corresponding variables) are uninitialized. Thus, you're ending up reading the value of an uninitialized variable sj
, which leads to undefined behavior。
你可以试试
struct s myStruct = {9};
查看隐式初始化的实际效果。
当你这样做时:
struct s myStruct;
myStruct.si = 9;
您没有初始化 myStruct
。你声明它 没有初始化器 ,然后 运行 一条语句来设置一个字段。
由于变量未初始化,其内容未定义,读取为undefined behavior。这意味着看似无关的更改可以修改此行为。在您的示例中,添加一个额外的变量 happened 会导致 myStruct.sj
为 0,但不能保证会是这种情况。
要初始化一个变量,你必须在定义时给它一个值:
struct s myStuct = { 9 };
执行此操作后,您会看到 myStruct.sj
的内容设置为 0。这是根据 the C standard 的第 6.7.8 节保证的(突出显示特定于此情况) :
10 If an object that has automatic storage duration is not
initialized explicitly, its value is indeterminate. If an object
that has static storage duration is not initialized
explicitly, then:
—if it has pointer type, it is initialized to a null
pointer;
—if it has arithmetic type, it is initialized to (positive or
unsigned) zero;
—if it is an aggregate, every member is initialized
(recursively) according to these rules;
—if it is a union, the first
named member is initialized (recursively) according to these rules.
...
21 If there are fewer initializers in a brace-enclosed list than there
are elements or members of an aggregate, or fewer characters in a
string literal used to initialize an array of known size than there
are elements in the array, the remainder of the aggregate
shall be initialized implicitly the same as objects that have static
storage duration.
这不是初始化程序——您的结构未初始化,因此您仅分配 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;
}
输出:
obj1.b : 0
obj2.b : 0
obj3.b : 0
obj4.b : 0
此 link 表示 "When an automatic array or structure has a partial initializer, the remainder is initialized to 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);
}
我不明白为什么当我注释掉 line no. 7
时打印 4096
(我相信它是一些 "garbage" 值),而当我取消注释 line no. 7
。我认为 arr
声明与 main()
的激活记录(或者更确切地说 myStruct
)没有任何关系,它应该看起来像(假设我们有 line no. 7
未注释):
---------------
| Saved PC |
---------------
| arr[2] |
---------------
| arr[1] |
---------------
| arr[0] |
---------------
| si |
---------------
| sj |
---------------
有人可以解释一下我在这里缺少什么吗?
在你的情况下,
myStruct.si = 9;
是一个assignment statement, not initialization. In this case, the structure variable (and the corresponding variables) are uninitialized. Thus, you're ending up reading the value of an uninitialized variable sj
, which leads to undefined behavior。
你可以试试
struct s myStruct = {9};
查看隐式初始化的实际效果。
当你这样做时:
struct s myStruct;
myStruct.si = 9;
您没有初始化 myStruct
。你声明它 没有初始化器 ,然后 运行 一条语句来设置一个字段。
由于变量未初始化,其内容未定义,读取为undefined behavior。这意味着看似无关的更改可以修改此行为。在您的示例中,添加一个额外的变量 happened 会导致 myStruct.sj
为 0,但不能保证会是这种情况。
要初始化一个变量,你必须在定义时给它一个值:
struct s myStuct = { 9 };
执行此操作后,您会看到 myStruct.sj
的内容设置为 0。这是根据 the C standard 的第 6.7.8 节保证的(突出显示特定于此情况) :
10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:
—if it has pointer type, it is initialized to a null pointer;
—if it has arithmetic type, it is initialized to (positive or unsigned) zero;
—if it is an aggregate, every member is initialized (recursively) according to these rules;
—if it is a union, the first named member is initialized (recursively) according to these rules.
...
21 If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.
这不是初始化程序——您的结构未初始化,因此您仅分配 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;
}
输出:
obj1.b : 0
obj2.b : 0
obj3.b : 0
obj4.b : 0