在C++中如何将数组的所有元素初始化为同一个默认值?

341

C++笔记:数组初始化列出了一个很好的数组初始化列表。我有一个

int array[100] = {-1};

我预期它应该完全由-1组成,但实际上只有第一个值是-1,其余都是0和随机值混合。

代码:

int array[100] = {0};

这段代码完全正常,并将每个元素设置为0。

我错过了什么吗?如果值不为零,不能初始化吗?

其次,这种默认的初始化方式(如上所述)比通常需要遍历整个数组并赋值的方法更快,还是它们执行的是相同的操作?


1
C和C++的行为是不同的。在C中,{0}是结构体初始化器的特殊情况,但据我所知,对于数组则不是。int array[100]={0}应该与array[100]={[0]=0}相同,这将副作用地将所有其他元素都设置为零。C编译器不应该像上面描述的那样行为,而是int array[100]={-1}应该将第一个元素设置为-1,其余元素设置为0(没有噪音)。在C中,如果你有一个struct x array[100],使用={0}作为初始化器是无效的。你可以使用{{0}},它将初始化第一个元素并将所有其他元素都设置为零,在大多数情况下将是相同的事情。 - Fredrik Widlund
1
@FredrikWidlund 在两种语言中都是一样的。{0} 对于结构体和数组都不是特殊情况。规则是没有初始化器的元素会被初始化为如果它们有一个初始化器,则为 0。如果有嵌套聚合体(例如 struct x array[100]),则初始化器按“行主”顺序应用于非聚合体;在这样做时,可以选择省略大括号。struct x array[100] = { 0 } 在 C 中是有效的;在 C++ 中也是有效的,只要 struct X 的第一个成员接受 0 作为初始化器即可。 - M.M
1
在C语言中,{ 0 }并不是特殊的,但是要定义一个不能用它进行初始化的数据类型却更加困难,因为没有构造函数,也就无法阻止0被隐式转换并赋值给某些东西 - Alex Celeste
3
投票重新开放,因为另一个问题是关于C语言的。有许多用于初始化数组的C++方法,在C语言中是无效的。 - xskxzr
1
也投票支持重新开放 - C和C ++是不同的语言。 - Pete
我删除了C标签,因为这个问题显然是关注于C++的,并相应地编辑了问题的标题。现在问题可以重新打开,因为它不再是一个重复的C问题。对于那些将来遇到这个问题并可能想查看同样的C问题的人,这里是链接:如何将数组的所有成员初始化为相同的值? - RobertS supports Monica Cellio
12个回答

1
在C++编程语言V4中,Stroustrup建议使用向量或值数组代替内置数组。对于值数组,当你创建它们时,你可以像这样将其初始化为特定的值:
valarray <int>seven7s=(7777777,7);

初始化一个长度为7,元素都为“7777777”的数组。
这是用C++数据结构而不是“纯旧C”数组实现答案的C++方式。
我改用valarray尝试在我的代码中使用C++特性而非C特性。

这是我见过的第二最糟糕的类型使用示例... - Steazy

1

1) 当您使用初始化程序时,对于结构体或类似数组的未指定值实际上是默认构造的。对于像int这样的原始类型,这意味着它们将被清零。请注意,这递归地应用:您可以有一个包含数组的结构体数组,如果您仅指定第一个结构体的第一个字段,则所有其余字段都将使用零和默认构造函数进行初始化。

2) 编译器可能会生成至少与手动编写的初始化代码一样好的初始化代码。当可能时,我倾向于让编译器为我执行初始化。


这里没有发生POD的默认初始化。使用列表,编译器将在编译时生成值并将它们放置在汇编的特殊部分中,该部分只是作为程序初始化的一部分加载(就像代码)。因此,在运行时成本为零。 - Martin York
1
我看不出他哪里错了?int a[100] = { } 肯定被初始化为全部为 0,无论它出现在哪里。struct { int a; } b[100] = { }; 也是如此。“本质上是默认构造的”=>“值构造”,虽然如此,但对于整数、PODS 或具有用户声明的构造函数的类型而言,这并不重要。仅对没有用户声明的构造函数的非 PODS 类型而言才重要,据我所知。但是我不会因为这个问题给您打一个反对票。不管怎样,您得到了 +1 的赞同,又把它变成了 0 :) - Johannes Schaub - litb
@Evan:我在我的陈述中加入了“当您使用初始化程序时…”的限定语。 我没有提到未初始化的值。@Martin:这可能适用于常量,静态或全局数据。 但我不知道如何处理以下内容:int test(){ int i[10]={0}; int v=i[0]; i[0]=5; return v; }每次调用test()时,编译器最好将i []初始化为零。 - Boojum
它可以将数据放入静态数据段,并使“i”引用它 :) - Johannes Schaub - litb
在技术上,对于这种情况,它也可以完全省略“i”,并返回0。但是,在多线程环境中使用静态数据段来处理可变数据是很危险的。我试图回答Martin的问题时想表达的观点只是你不能完全消除初始化的成本。从静态数据段复制一个预制块,当然可以,但仍然不是免费的。 - Boojum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接