C 用{0}或{';\0';}初始化结构之间有什么区别吗?

C 用{0}或{';\0';}初始化结构之间有什么区别吗?,c,struct,initialization,C,Struct,Initialization,一位同事建议用{'\0'}而不是{0}初始化结构,因为他解释说0被认为是int,因此至少有4个字节。因此,如果结构不是4的倍数,则将结构初始化为0可能会留下一些未初始化为0的字节,而因为\0是大小为1字节的ASCII字符,因此无论结构大小如何,它都会将结构初始化为零 话虽如此,我几乎从未见过使用{'\0'}进行初始化,但我确实看到了许多使用{0}的初始化 我的问题是用{0}初始化结构是否足够?这是否足够,因为大多数编译器会自动将不是4的倍数的字节填充为零,还是因为C这样做?是的,用{0}初始化结

一位同事建议用
{'\0'}
而不是
{0}
初始化结构,因为他解释说
0
被认为是
int
,因此至少有4个字节。因此,如果结构不是4的倍数,则将结构初始化为
0
可能会留下一些未初始化为
0
的字节,而因为
\0
是大小为1字节的ASCII字符,因此无论结构大小如何,它都会将结构初始化为零

话虽如此,我几乎从未见过使用
{'\0'}
进行初始化,但我确实看到了许多使用
{0}
的初始化


我的问题是用
{0}
初始化结构是否足够?这是否足够,因为大多数编译器会自动将不是4的倍数的字节填充为零,还是因为C这样做?

是的,用{0}初始化结构就足够了。理解编译器不会基于初始化将内存分配给struct。与是否填充了某个值无关的结构总是需要相同的内存

e、 g

#包括
结构A{
字符a;
};
结构B{
int b;
};
内部主(空){
结构A b={'\0'};
结构A c={0};
printf(“%zu%zu\n”,sizeof(b),sizeof(c));
结构B ab={'\0'};
结构B ac={0};
printf(“%zu%zu\n”、sizeof(ab)、sizeof(ac));
返回0;
}

答案总是一样的,与你如何分配答案无关。

不,没有区别

例如,
'\0'
不是“一个字节”;在C语言中,字符常量的类型为
int
,因此
'\0'
0
在每个上下文中都是100%等效的。(您可以使用
sizeof
进行检查:
sizeof 0
sizeof'\0'
将产生相同的值,通常为4或8。)

另一个原因在C的初始化规则中有解释(在C99中是6.7.8初始化):

[……]

  • 否则,具有聚合或联合类型的对象的初始值设定项应为元素或命名成员的括号内初始值设定项列表

  • 每个括号内的初始值设定项列表都有一个关联的当前对象。当没有 如果存在指定,则当前对象的子对象将根据顺序初始化 到当前对象的类型:按递增下标顺序排列的数组元素,结构 按声明顺序排列的成员,以及工会的第一个指定成员。[……]

  • 这表示初始化列表的成员用于按顺序初始化结构或数组的字段;它们有多少字节并不重要

    如果你写信

    struct foo { double x; };
    struct foo var = { 0 };
    
    然后使用
    0
    (第一个初始值设定项值,类型
    int
    )初始化第一个结构字段(
    x
    ,类型
    double
    )。这就好像您编写了
    double x=0
    。其效果是
    0
    的值从
    int
    隐式转换为
    double
    ,并存储在变量中

    此外,如果初始值设定项少于结构或数组元素,则此规则适用:

  • 如果括号内列表中的初始值设定项少于元素或成员 用于初始化已知数组的聚合或字符串文字中的更少字符 尺寸大于阵列中的元素,则骨料的剩余部分应为 与具有静态存储持续时间的对象隐式初始化相同
  • 那么隐式初始化如何处理静态对象呢

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

    • 如果有指针类型,则初始化为空指针
    • 如果它有算术类型,则初始化为(正或无符号)零
    • 如果是聚合,则根据这些规则(递归地)初始化每个成员
    • 如果是联合,则根据这些规则(递归地)初始化第一个命名成员
  • 这意味着数组或结构的所有未显式初始化的成员都隐式设置为0

    struct foo { double x; };
    struct foo var = { 0 };