在我的c++程序中,我试图初始化一个类型为3*3*3的双精度数组,所有的0。在类头文件中,我声明了一个成员
double list[3][3][3];
当我打印出这个数组的内容时,我发现并不是所有的条目都像我期望的那样是0。例如,list[1][1][1]的值为4.03158e-321
因此,我手动将这个数组初始化为构造函数中的所有0:
list = {{{0,0,0},{0,0,0},{0,0,0}},
{{0,0,0},{0,0,0},{0,0,0}},
{{0,0,0},{0,0,0},{0,0,0}}};
这使我的程序工作,然而,我得到编译器警告:
warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x
所以我的问题是
- 为什么list在初始化后有非零条目头吗?
- 为什么我得到上述警告消息,以及如何摆脱它?
我的编译器是g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2, gcc版本4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)
在c++ 03中,你只能在定义数组时使用这个初始化:
double list[3][3][3] = {{{0,0,0},{0,0,0},{0,0,0}},
{{0,0,0},{0,0,0},{0,0,0}},
{{0,0,0},{0,0,0},{0,0,0}}};
编译器警告,根据当前的标准,它不应该接受你的代码,即使它能够通过应用即将到来的标准规则来处理它,其中{...}
被称为外部初始化器。
在这种特殊情况下,如果数组是一个成员,并且您希望将其初始化为全零,则可以在c++ 0x:
中使用value-initializationstruct test {
double list[3][3][3];
test() : list()
{}
};
对于POD类型的成员(double
的数组),上面的语法(list()
)在初始化列表中意味着该成员是值初始化的,这实际上意味着所有值将被设置为0
是我错过了什么,还是你可以不做
class Class {
public:
double array[3][3][3];
Class() : array() { }
};
-
头文件中没有初始化,只是声明了。内置类型(以及更一般的pod)如果不是全局类型(实际上,它们具有静态存储持续时间),则不会出于性能原因自动进行零初始化(与c++中的许多事情一样,初始化是可选的,只有在需要时才付费)。
-
该语法仅在初始化数组时有效,而该指令是赋值。在新的c++标准(以前是c++ 0x,现在是c++ 11,因为它刚刚被批准)中,这种语法可以在更多的地方使用。
在我看来,解决你的问题最快的方法就是这样做:
double * firstElem=&list[0][0][0];
std::fill(firstElem, firstElem+27, 0.);
将list
视为由27个double
组成的一维数组,并将其填充为零(这里有关于该技巧的更多信息)。
注意,这个参数也在数组FAQ中被简单处理过。
有一种更简单的方法。以下代码应该在C或c++中工作,仅用于初始化变量(即不在赋值中):
double list[3][3][3] = {0};
{0}是一个特殊的初始化器,它可以将几乎所有结构设置为全零。
为什么不使用memset
或loop将值设置为零呢?