字符串文字是否计为部分初始化程序并进行零初始化?

时间:2012-08-02 15:24:58

标签: c string initialization literals

在C中,您可以部分初始化结构或数组,结果是初始化程序中未提及的成员/元素被零初始化。 (C99第6.7.8.19节)。例如: -

int a[4] = {1, 2};
// a[0] == 1
// a[1] == 2
// a[2] == 0
// a[3] == 0

您还可以使用字符串文字(C99第6.7.8.14节)和“连续字符...初始化数组元素”初始化“字符数组数组”。例如: -

char b[4] = "abc";
// b[0] == 'a'
// b[1] == 'b'
// b[2] == 'c'
// b[3] == '\0'

一切都很简单。但是如果你明确给出数组的长度会发生什么,但是使用太短的文字来填充数组呢?剩余的字符是否已初始化,或者它们是否具有未定义的值?

char c[4] = "a";
// c[0] == 'a'
// c[1] == '\0'
// c[2] == ?
// c[3] == ?

将其作为部分初始化程序处理是有意义的,它会使char c[4] = "a"的行为与char c[4] = {'a'}完全相同,并且它会产生有用的副作用,让您简明地对整个字符数组进行零初始化使用char d[N] = "",但我并不清楚这是规范所要求的。

3 个答案:

答案 0 :(得分:14)

 char c[4] = "a";

阵列的所有剩余元素将设置为0。也就是说,不仅c[1]而且c[2]c[3]

请注意,这不取决于c的存储持续时间,即。例如,即使c具有自动存储持续时间,其余元素也将设置为0

从C标准(强调我的):

  

(C99,6.7.8p21)“如果括号括起的列表中的初始值设定项少于聚合的元素或成员,则字符串文字中的或更少的字符用于初始化已知大小的数组比数组中的元素大,其余的聚合应隐式初始化,与具有静态存储持续时间的对象相同。

答案 1 :(得分:7)

根据C99标准(如ouah所述):

  

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

  

如果未明确初始化具有自动存储持续时间的对象,   它的价值是不确定的。如果具有静态存储持续时间的对象是   没有明确初始化,那么:

     
      
  • 如果它有指针类型,则将其初始化为空指针;
  •   
  • 如果它有算术类型,则初始化为(正数或无符号)零;
  •   
  • 如果是聚合,则根据这些规则初始化(递归)每个成员;
  •   
  • 如果它是一个联合,则根据这些初始化(递归)第一个命名成员   规则。
  •   

char是算术类型,因此数组的其余元素将初始化为零。

答案 2 :(得分:3)

在C语言中,它始终遵循 all-or-nothing 初始化方法。如果仅部分初始化聚合,则该聚合的其余部分将初始化为零。

可以说,这对于字符串而言是过度的而不是最优的,但这就是它在C中的工作原理。