让我说我有:
char name[16] = "123456789abc";
所以name[11] == 'c'
,name[12] == '\0'
。
name[13]
是否会依赖于胡言乱语/编译器,或者它是否可靠地成为特定值(例如'\ 0'?)
答案 0 :(得分:8)
从字符串文字初始化字符数组时,未使用的元素初始化为零。
第8.5.2节有规则:
窄字符类型(3.9.1),
char16_t
数组,char32_t
数组或wchar_t
数组的数组可以通过窄字符串文字char16_t
初始化字符串文字,char32_t
字符串文字或宽字符串文字,或者用括号括起来的适当类型的字符串文字(2.14.5)。字符串文字值的连续字符初始化数组的元素。没有比数组元素更多的初始化器。
如果初始化器的数量少于数组元素,则未明确初始化的每个元素都应进行零初始化(8.5)。
因此,它们将为零。保证。
访问它们并非未定义的行为。
如果您从字符列表char name[16] = { '1', '2', '3', '4', '5', 0 };
初始化,那么您将处于聚合初始化领域,这会通过不同的路径提供相同的结果。
当使用聚合初始化并且初始化器的数量少于聚合的元素时,剩余部分的值是初始化的(除非在聚合类型的定义中有 brace-or-equal-initializer )。
该规则见8.5.1节
如果初始化子句的数量超过要初始化的成员或元素的数量,则初始化列表格式不正确。
如果列表中的初始化子条款少于聚合中的成员,则未明确初始化的每个成员应从其大括号或等号初始值初始化,或者如果没有大括号 - or-equal-initializer,来自空的初始化列表(8.5.4)。
并且有一个例子:
struct S { int a; const char* b; int c; int d = b[a]; }; S ss = { 1, "asdf" };
使用
ss.a
初始化1
,ss.b
"asdf"
,ss.c
初始化int{}
形式的表达式值(那 是,0
)和ss.d
,其值为ss.b[ss.a]
(即's'
)
C ++ 03没有明确声明额外元素将在字符数组规则中进行零初始化。另一方面,聚合规则基本相似,并保证值初始化,始终( brace-or-equal-initializer 在C ++ 11中引入)。
C99第6.7.8节在两种情况下均提供零初始化,即:
如果括号括起的列表中的初始值设定项少于元素或成员 用于初始化已知数组的字符串文字中的聚合或更少字符 大小比数组中的元素大,其余的聚合应该是 隐式初始化与具有静态存储持续时间的对象相同。
当然,具有静态存储持续时间的对象已预先初始化为零。