矢量将所有负值转换为零

Suh*_*tar 31 c++ vector data-structures

我制作了一个恒定大小的矢量来存储负值,然后打印所有我得到的值是零.我只是想知道它为什么不存储负值.

#include <iostream>
#include <vector>

int main() {
    std::vector<int> v(5);
    v.push_back(-1);
    v.push_back(-2);
    v.push_back(-3);
    v.push_back(-4);
    v.push_back(-5);

    for (int i=0; i<5; i++)
       std::cout << v[i] << " ";  // All I got was zeroes
}
Run Code Online (Sandbox Code Playgroud)

Bat*_*eba 53

那是因为push_back元素放在向量的末尾.

您可以通过运行看看效果i9:负数将占据v[5]v[9].

写作

std::vector<int> v{-1, -2, -3, -4, -5};
Run Code Online (Sandbox Code Playgroud)

相反是一个特别优雅的修复.

  • 你是一个优雅的解决方案. (9认同)
  • @SuhailAkhtar:根本不是一个坏问题:Java在构造函数参数设置*capacity*的情况下反过来. (7认同)
  • @SuhailAkhtar对[array](https://en.cppreference.com/w/cpp/language/array)s的限制(在运行时固定的最大大小)是正确的.与"经典"数组类型相比,向量的灵活性增加以及它们(通常)较小的运行时开销使它们如此受欢迎. (2认同)

lub*_*bgr 25

您调用的构造函数用零填充前5个元素,请参见此处(重载列表中的#3):

使用计数默认插入的T实例构造容器

(其中"默认插入的实例" int为0).你可能想要的是

std::vector<int> v;

v.reserve(5); /* Prevent unnecessary allocations as you know the desired size. */

v.push_back(-1);
/* ... */
Run Code Online (Sandbox Code Playgroud)

使用原始构造函数调用的替代方法是

#include <numeric>

std::vector<int> v(5);

std::iota(v.rbegin(), v.rend(), -v.size());
Run Code Online (Sandbox Code Playgroud)

虽然这比必要的工作更多,因为每个元素首先默认构造,然后再次分配给新值.


Rus*_*lan 12

这是DRY原则可以帮助您理解错误的情况.

vector<int> v(5);

...

for(int i=0;i<5;i++)

在这里,您要创建一个数组,您认为可以为5个元素保留空间.然后插入这5个元素.之后你想打印整个数组的内容,但不是只写v.size(),而是重复了5,所以你的代码现在读起来像"打印前五个元素v",而不是"打印所有元素v".

如果你改写了你的意思,你会发现数组实际上有10个元素,而不是5个元素.

顺便说一句,从C++ 11开始,您可以以更直接的方式遍历所有元素:

for(int x : v)
Run Code Online (Sandbox Code Playgroud)

或者,如果元素是更复杂的类型,您可以使用对元素的auto引用,甚至是类型引用:

for(auto& x : v)
Run Code Online (Sandbox Code Playgroud)

这种新循环for语法称为基于范围的for循环.


hii*_*sui 5

您可以vector在C/C++中考虑原始数组的灵活版本.当你vector用一个大小初始化a 时n,构造的vector大小n(或者在内存中可能更大,但你不知道,因为它是由编译器隐式处理的).请注意,此处n表示条目数,但不表示实际内存使用量(即字节数).如果不使用size参数初始化它,vector则为空,大小为0,但在内存中它将具有一些隐式默认内存大小.

假设您的当前vector大小为5.并且您希望push_back()在另一个元素中,然后vector内部将整个阵列重新分配到一个新的内存位置,该位置可以容纳所有旧条目和新条目.所以你不需要自己手动重新分配内存,就像你在C中必须做的那样.

在您的示例中,要填写您的5个负整数vector,有两种方法.

1)您可以在vector不指定大小的情况下初始化a .然后推入你想要的每个元素.

vector<int> v;
for (int i = -1; i >= -5; --i) {
    v.push_back(i);
}
Run Code Online (Sandbox Code Playgroud)

2)您可以vector使用该size参数初始化.然后为它们分配新值.

vector<int> v(5);
for (int i = 0; i < v.size(); ++i) {
    v[i] = -i;
}
Run Code Online (Sandbox Code Playgroud)

3)您还可以vector在构造时使用这些条目初始化.

    vector<int> v{-1, -2, -3, -4, -5};
or  vector<int> v = {-1, -2, -3, -4, -5};
Run Code Online (Sandbox Code Playgroud)