像这样初始化数组中的某些元素是否安全?
const char *str_array[50] = {
[0] = "str_0",
[10] = "str_10",
[24] = "str_24",
[45] = "str_45",
};
我可以依赖正确初始化数组的其他元素吗?
答案 0 :(得分:2)
是的,这很安全。
请参阅N1570第6.7.9节。
第19段,讨论初始化列表:
...所有未明确初始化的子对象应为 隐式初始化与具有静态存储的对象相同 持续时间。
第10段:
如果未初始化具有自动存储持续时间的对象 显然,它的价值是不确定的。如果一个对象有静态 或线程存储持续时间未明确初始化,然后:
- 如果它有指针类型,则将其初始化为空指针;
- 如果它有算术类型,则初始化为(正或无符号)零; - 如果它是一个聚合,则根据这些规则初始化(递归)每个成员,并将任何填充初始化为零位;
- 如果是联合,则根据这些规则初始化(递归)第一个命名成员,并将任何填充初始化为零位;
答案 1 :(得分:2)
问题中显示的初始化是安全的,未使用指定的初始化程序专门初始化的元素(在此上下文中)初始化为NULL。通常,未初始化的元素初始化与初始化相同类型的静态变量相同,这是“零”主题的一些变化。
C标准(ISO / IEC 9899:2011)的相关部分为§6.7.9 Initialization,具体为¶19:
初始化应在初始化器列表顺序中进行,每个初始化器为特定子对象提供,覆盖同一子对象的任何先前列出的初始化器; 151)所有未明确初始化的子对象应隐式初始化与具有静态存储持续时间的对象相同。
151)对子对象的任何初始化程序都被覆盖,因此不会用于初始化该子对象,可能根本不会进行评估。
评论中有一个反驳:
如果我希望其他元素设置为相同的默认值怎么办?
不幸的是,您必须选择NULL(在这种情况下;在一般情况下为零)作为默认值。你在标准C中没有任何其他选择(不像复杂的现代语言,哦,我不知道 - 让我们想到Fortran 66)。除了多次写入之外,标准C中没有办法重复初始化器。
GCC有一个扩展允许您这样做(在GCC手册中记录的标题为Designated Initializers的部分记录了标准行为和非标准行为)。使用GNU扩展,您可以写:
const char *str_array[50] = {
[1 ... 49] = "empty string", // GCC extension
[0] = "str_0",
[10] = "str_10",
[24] = "str_24",
[45] = "str_45",
};
注意,可以为单元格指定两个初始值设定项(例如10,24,45 - 另一个是通过重复的初始化程序);最后一个提到胜利。另请注意...
与1
(和45
)之间的空格;这是至关重要的,因为“最大咀嚼规则”意味着[1...45]
将被标记为[
,1.
,.
,.45
,{{1其中浮点数不是你想要的。