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

在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] = ""简洁地初始化一个完整的字符数组,但对我来说这根本不清楚这是规范所要求的。

  char c[4] = "a"; 

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

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

从C标准(强调我的):

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

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

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

和:

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

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

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

在C语言中,它始终遵循全有或全无的初始化方法。 如果仅部分初始化聚合,则该聚合的其余部分将初始化为零。

可以说这对于弦乐来说是过度的而不是最优的,但这就是它在C中的工作方式。