数组未在 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++ 中使用花括号进行初始化的主要内容,如果未能解决你的问题,请参考以下文章

差异方法初始化char数组

C++ C++ Primer 基础知识笔记

C++ C++ Primer 基础知识笔记

c语言共用体包含一个数组成员,我要对这个数组成员进行赋值,一定要一个一个的赋值么?不能写在花括号

C++ C++ Primer 基础知识笔记

C++中带括号的数组对象的初始化