15

在 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] = ""

4

3 回答 3

15
 char c[4] = "a";

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

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

来自 C 标准(强调我的):

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

于 2012-08-02T15:27:24.050 回答
8

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

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

和:

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

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

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

于 2012-08-02T15:36:52.963 回答
3

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

可以说这对于字符串来说是过度的并且不是最佳的,但这就是它在 C 中的工作方式。

于 2012-08-02T15:54:29.117 回答