在C语言中初始化字符指针数组

在C语言中初始化字符指针数组,c,arrays,pointers,C,Arrays,Pointers,像这样初始化数组中的某些元素安全吗 const char *str_array[50] = { [0] = "str_0", [10] = "str_10", [24] = "str_24", [45] = "str_45", }; 我可以依靠数组的其他元素被正确初始化吗?是的,它非常安全 见第6.7.9节 第19段,讨论起首字母表: 。。。所有未显式初始化的子对象都应 与具有静态存储的对象隐式初始化相同 持续时间 第10段: 如果未初始化具有自动存储持续时间的

像这样初始化数组中的某些元素安全吗

const char *str_array[50] = {
    [0] = "str_0",
    [10] = "str_10",
    [24] = "str_24",
    [45] = "str_45",
};
我可以依靠数组的其他元素被正确初始化吗?

是的,它非常安全

见第6.7.9节

第19段,讨论起首字母表:

。。。所有未显式初始化的子对象都应 与具有静态存储的对象隐式初始化相同 持续时间

第10段:

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

  • 如果有指针类型,则初始化为空指针
  • 如果它有算术类型,则初始化为(正或无符号)零; -如果它是一个聚合,则根据这些规则(递归地)初始化每个成员,并将任何填充初始化为零位
  • 如果它是一个并集,则根据这些规则(递归地)初始化第一个命名成员,并将任何填充初始化为零位
是的,很安全

见第6.7.9节

第19段,讨论起首字母表:

。。。所有未显式初始化的子对象都应 与具有静态存储的对象隐式初始化相同 持续时间

第10段:

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

  • 如果有指针类型,则初始化为空指针
  • 如果它有算术类型,则初始化为(正或无符号)零; -如果它是一个聚合,则根据这些规则(递归地)初始化每个成员,并将任何填充初始化为零位
  • 如果它是一个并集,则根据这些规则(递归地)初始化第一个命名成员,并将任何填充初始化为零位

问题中显示的初始化是安全的,未使用指定的初始值设定项专门初始化的元素(在此上下文中)初始化为NULL。通常,未初始化的元素的初始化方式与相同类型的静态变量的初始化方式相同,这是“零”主题的一些变体

C标准(ISO/IEC 9899:2011)的相关章节是,特别是¨19:

初始化应按初始值设定项列表顺序进行,为特定子对象提供的每个初始值设定项都将覆盖之前为同一子对象列出的任何初始值设定项;151)所有未显式初始化的子对象应隐式初始化,与具有静态存储持续时间的对象相同

151)子对象的任何初始值设定项如果被覆盖,因此不用于初始化该子对象,则可能根本不会进行计算

评论中有一项反驳:

如果我希望其他元素设置为相同的默认值,该怎么办

不幸的是,您必须选择NULL(在本例中为零,在一般情况下为零)作为默认值。在标准C中没有任何其他选择(不像复杂的现代语言,例如,哦,我不知道——让我们想想Fortran 66)。在标准C中,除了多次写入初始值设定项之外,没有其他方法可以重复初始值设定项

GCC有一个扩展,允许您这样做(在GCC手册中的一个章节中记录了该扩展,标题为记录标准行为和非标准行为)。使用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
]
,其中浮点数不是需要的。

问题中显示的初始化是安全的,并且没有使用指定的初始值设定项专门初始化的元素(在此上下文中)被初始化为NULL。通常,未初始化的元素的初始化方式与相同类型的静态变量的初始化方式相同,这是“零”主题的一些变体

C标准(ISO/IEC 9899:2011)的相关章节是,特别是¨19:

初始化应按初始值设定项列表顺序进行,为特定子对象提供的每个初始值设定项都将覆盖之前为同一子对象列出的任何初始值设定项;151)所有未显式初始化的子对象应隐式初始化,与具有静态存储持续时间的对象相同

151)子对象的任何初始值设定项如果被覆盖,因此不用于初始化该子对象,则可能根本不会进行计算

评论中有一项反驳:

如果我希望其他元素设置为相同的默认值,该怎么办

不幸的是,您必须选择NULL(在本例中为零,在一般情况下为零)作为默认值。在标准C中没有任何其他选择(不像复杂的现代语言,例如,哦,我不知道——让我们想想Fortran 66)。在标准C中,除了多次写入初始值设定项之外,没有其他方法可以重复初始值设定项

GCC有一个扩展,允许您这样做(在GCC手册中的一个章节中记录了该扩展,标题为记录标准行为和非标准行为)。使用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-另一个是通过重复的初始值设定项);最后一个是曼蒂