2013-12-13 52 views
1

我正在学习C++,我已经遇到了以下奇怪的初始化:阵列不与C++中的花括号

如果我初始化类的书阵列说

int my_array[5] = {10} 

每个数组字段仍然初始化为零,当它应该为十。

如果我在一个循环中初始化它,它按预期工作

这是怎么回事?我正在使用Ubuntu并使用g ++编译

+1

*第一个*之后的每个*字段或每个字段*? –

+0

只有第一个元素是10,其余的0 – Praetorian

+0

确实,第一个元素是10(在检查数组内容时我的错误是这样) –

回答

7

您观察的结果是正确的:根据标准,数组的其余项被初始化为0。

+0

是的,我看到这是正确的行为。我正在使用的教程说,通过使用数组[5] = {0},您可以将所有内容初始化为零。我错误地认为它可以处理所有的值。 –

+1

@MarkoKacanski该方法对于值0是最佳的,因为编译器可以按任意顺序分配所有值0,并且实质上优化自身。在增量for循环中执行同样的操作并不理想,因为您为所有元素指定迭代器,顺序和值。但是,这是我知道初始化为非零值的唯一方法。 ('std :: fill_n'在内部工作原理相同) – Trojan

+1

使用'= {0}'与使用'= {}'相同,并且让编译器隐式地为您初始化第一个元素。换句话说,当使用大括号时,您明确指定的任何值都只会将该字段初始化为该特定值,然后任何未指定的字段将被初始化为零。所以如果你省略了第一个字段,编译器会为你简单地初始化它。 –

4

当使用小于的列表进行初始化时,只会按照您的预期初始化指定的元素;其余部分初始化为0.

要初始化所有值,请使用循环或std::fill_n,如here所示。

std::fill_n(my_array, 5, 10); // array name, size, value 

在内部,std::fill_n相当于一个循环。从第一个环节:

template <class OutputIterator, class Size, class T> 
    OutputIterator fill_n (OutputIterator first, Size n, const T& val) 
{ 
    while (n>0) { 
     *first = val; 
     ++first; --n; 
    } 
    return first;  // since C++11 
} 
6

的C++ 03(假定,如果你有GCC的Ubuntu系统上的旧版本)标准说:

8.5.1/7

如果列表中的初始化器数量少于总数中的成员 ,则未明确初始化的每个成员应该是数值初始化的()。

和阵列是一个聚合:

8.5.1/1

聚集是一个阵列或类(第9节),没有用户声明的 构造( 12.1),没有私人或受保护的非静态数据成员 (第11条),没有基类(第10条),也没有虚拟函数 (10.3)。

至于什么值初始化装置:

要值初始化类型T的对象是指:

- 如果T是一个类型(第9节)与用户声明的构造函数(12.1),那么调用T的默认构造函数(并且如果T没有可访问的默认构造函数,则初始化不合格);

...并且跳过一切int不是...

- 否则,对象是零初始化

这是int类型的变量会发生什么。

+0

这正是我想发布的支持信息。你有这个标准的副本吗?或者你看一些在线资源? – Jarhmander

+0

@Jarhmander只需谷歌它。 – 2013-12-13 21:41:50

+0

那我的谷歌真可怕,我很害怕。 – Jarhmander