C++ 将常量字符串分配给一个大小恒定的字符数组,在未使用的数组索引中会发生什么?
假设我有:C++ 将常量字符串分配给一个大小恒定的字符数组,在未使用的数组索引中会发生什么?,c++,c++11,C++,C++11,假设我有: char name[16] = "123456789abc"; 因此,name[11]=='c',name[12]=='0' name[13]是否会胡言乱语/取决于编译器,或者它是否会可靠地成为特定值(例如“\0”?)当字符数组从字符串文字初始化时,未使用的元素会初始化为零 第8.5.2节规定: 窄字符类型(3.9.1)、char16\u tarray、char32\u tarray或wchar\u tarray的数组可以分别由窄字符串文字、char16\u t字符串文字、char
char name[16] = "123456789abc";
因此,name[11]=='c'
,name[12]=='0'
name[13]
是否会胡言乱语/取决于编译器,或者它是否会可靠地成为特定值(例如“\0”?)当字符数组从字符串文字初始化时,未使用的元素会初始化为零
第8.5.2节规定:
窄字符类型(3.9.1)、char16\u t
array、char32\u t
array或wchar\u t
array的数组可以分别由窄字符串文字、char16\u t
字符串文字、char32\u t
字符串文字或宽字符串文字初始化,或者使用大括号中包含的适当类型的字符串文字(2.14.5)。字符串文本值的连续字符初始化数组的元素
初始值设定项的数量不得超过数组元素的数量
如果初始值设定项少于数组元素,则未显式初始化的每个元素应为零初始化(8.5)。
因此,它们将为零。保证
访问它们并不是未定义的行为
如果您是从字符列表中初始化的,而不是
字符名[16]={'1','2','3','4','5',0}代码>,您将处于聚合初始化领域,它通过不同的路由提供相同的结果
如果使用聚合初始化,并且初始化器少于聚合的元素,则剩余的初始化器为值初始化(除非聚合类型的定义中有大括号或相等的初始化器)
该规则见第8.5.1节
如果初始值设定项子句的数量超过要初始化的成员或元素的数量,则初始值设定项列表的格式不正确
如果列表中的初始值设定项子句少于聚合中的成员,则未明确初始化的每个成员应使用大括号或同等初始值设定项进行初始化,如果没有大括号或同等初始值设定项,则使用空初始值设定项列表(8.5.4)进行初始化。
这里有一个例子:
用1
初始化ss.a
,ss.b
用“asdf”
,ss.c
用int{}
形式的表达式的值进行初始化(表示
是,0
),和ss.d
,其值为ss.b[ss.a]
(即,'s'
)
C++03没有明确声明在字符数组规则中额外的元素将被零初始化。另一方面,聚合规则在本质上是相似的,并且始终保证值初始化(C++11中引入了大括号或相等的初始值设定项)
C99第6.7.8节在两种情况下均提供零初始化,即:
如果括号内列表中的初始值设定项少于元素或成员
用于初始化已知数组的聚合或字符串文字中的更少字符
尺寸大于阵列中的元素,则骨料的剩余部分应为
与具有静态存储持续时间的对象隐式初始化相同
当然,具有静态存储持续时间的对象被预先初始化为零。Spot on,+1。我不知道这实际上是一种“聚合初始化”。您可能想发布(非标准)字符串文本似乎不需要init列表。@vsoftco:事实上,您是对的,它不是聚合初始化。我找到了错误的规则。但是,它们仍然初始化为零。@πάνταῥεῖ 我发现我自己比C++更难学习C++标准:)我不知怎么放弃了所有这些细节,每当编写代码时,我试图使它变得清晰。谢谢实现零终止的原因也在相关情况下?πάνταῥεῖ 提出了一个有效的观点——如果您没有高质量的编译器,最好不要假设它遵循此规则。(亦称:)
struct S { int a; const char* b; int c; int d = b[a]; };
S ss = { 1, "asdf" };