数组未在 C++ 中使用花括号进行初始化
Posted
技术标签:
【中文标题】数组未在 C++ 中使用花括号进行初始化【英文标题】:Array doesn't initialize with a curly braces in c++ 【发布时间】:2013-12-13 21:17:24 【问题描述】:我在学习c++,遇到了如下奇怪的事情:
如果我像书上说的那样初始化数组
int my_array[5] = 10
每个数组字段仍然初始化为零,而它应该是十。
如果我在循环中初始化它,它会按预期工作
发生了什么?我正在使用 Ubuntu 并使用 g++ 进行编译
【问题讨论】:
每个字段,还是第一个之后的每个字段? 只有第一个元素为 10,其余为 0 确实,第一个元素是 10(我在检查数组内容时弄错了) @MarkoKacanski:我可以保证第一个数组元素my_array[0]
被初始化为10
。
@MarkoKacanski:我不买。第一个元素是 10,所有其他元素都是 0
【参考方案1】:
您观察到的是正确的:根据标准,数组的其余项被初始化为 0。
【讨论】:
是的,我发现这是正确的行为。我正在使用的教程说,通过使用 array[5] = 0 可以将所有内容初始化为零。我错误地认为它适用于所有值。 @MarkoKacanski 该方法对于值 0 是最佳的,因为编译器可以按任何顺序分配所有值 0,并从本质上优化自身。在增量 for 循环中执行相同的操作不是最优的,因为您为所有元素指定了迭代器、顺序和值。但是,这是初始化为非零值的唯一方法(据我所知)。 (std::fill_n
内部工作方式相同)
使用= 0
与使用=
相同,并让编译器为您隐式零初始化第一个元素。换句话说,当使用大括号时,您明确指定的任何值都只会将该字段初始化为该特定值,然后任何未指定的字段将被零初始化。因此,如果您省略第一个字段,编译器将简单地为您将其初始化为零。
Marko,你的书说的是真的,尽管如果这就是它所说的一切,那就是误导。第一个元素初始化为零的原因与其余元素初始化为零的原因不同。你的书应该提到这种区别,也许是通过使用你在问题中引用的例子。我曾经假设和你一样。【参考方案2】:
C++03(假设您在 Ubuntu 系统上使用旧版本的 GCC)标准说:
8.5.1/7
如果列表中的初始化器数量少于成员数量 总的来说,那么每个未显式初始化的成员都应该是 值初始化 (8.5)。
数组是一个聚合:
8.5.1/1
聚合是一个 array 或一个没有用户声明的类(第 9 条) 构造函数(12.1),没有私有或受保护的非静态数据成员 (第 11 条),没有基类(第 10 条),没有虚函数 (10.3)。
关于值初始化是什么意思:
对 T 类型的对象进行值初始化意味着:
——如果 T 是具有用户声明的构造函数 (12.1) 的类类型(第 9 条),则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化是非良构的);
...跳过所有 int 不是...
——否则,对象被零初始化
int
类型的变量会发生什么情况。
【讨论】:
这正是我想要发布的支持信息。您是否有该标准的副本或查看一些在线资源?【参考方案3】:当使用列表小于数组进行初始化时,只有指定的元素会按预期进行初始化;其余的都初始化为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
【讨论】:
以上是关于数组未在 C++ 中使用花括号进行初始化的主要内容,如果未能解决你的问题,请参考以下文章