8

假设以下初始化:

char mystr[4] = "";

C99 标准是否保证初始化为空字符串的字符数组会将字符数组中的所有元素初始化为空字节?例如,标准是否保证mystr[2] == '\0'

这些初始化怎么样:

char myfoo[4] = { '\0' };
char mybar[4] = { 0 };

虽然我很确定显式设置字符数组的第一个元素将保证其余元素的隐式初始化为0,但我怀疑字符串文字初始化会导致复制到数组 - 因此意味着复制单个 \0到数组,而其余元素未初始化。

4

3 回答 3

12

第 6.7.8 节第 21 段:

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

以及如何初始化具有静态存储持续时间的对象?

第 6.7.8 节第 10 段:

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

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

char 是算术类型,所以初始化为0。呵呵,你放心吧。

于 2013-06-06T22:01:33.930 回答
6

C 语言对所有聚合初始化都遵循“全有或全无”的方法。这意味着任何为聚合的任何部分(无论该部分有多小)提供显式初始化程序的任何尝试都会立即保证整个聚合将被初始化。没有显式初始化器的部分将被初始化为零。

在您的示例中,整个数组保证用零初始化。在结构初始化的情况下,所有未显式初始化的字段都将获得零值。

该原则的一个结果是,在 C 语言中,= { 0 }初始化程序用作惯用的通用零初始化程序。由于该语言也允许= { value }在标量对象初始化器中使用语法,因此可以使用将任何= { 0 }对象初始化为全零状态

#define UNIVERSAL_ZERO { 0 }

double d = UNIVERSAL_ZERO;
char s[100] = UNIVERSAL_ZERO;
struct { int x, y, z; } xyz = UNIVERSAL_ZERO;
int *p = UNIVERSAL_ZERO;
于 2013-06-06T23:34:14.883 回答
4

是的,数组的多余元素总是零初始化,char使用字符串字面量初始化的数组也不例外。

来自 C99 标准,第 6.7.8.21 节(本文档第 139 页):

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

于 2013-06-06T21:39:46.953 回答