【问题标题】:Array doesn't initialize with a curly braces in c++数组未在 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

标签: c++ arrays


【解决方案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
}

【讨论】:

    猜你喜欢
    • 2017-06-30
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多