向量将所有负值转换为零

时间:2018-07-13 07:06:48

标签: 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
}

6 个答案:

答案 0 :(得分:53)

这是因为push_back new 元素放在向量的末尾。

通过将i9可以看到效果:负数将占据v[5]v[9]

写作

std::vector<int> v{-1, -2, -3, -4, -5};

相反,这是一个特别优雅的修复程序。

答案 1 :(得分:25)

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

  

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

(其中int的“默认插入实例”为0)。您可能想要的是

std::vector<int> v;

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

v.push_back(-1);
/* ... */

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

#include <numeric>

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

std::iota(v.rbegin(), v.rend(), -v.size());

尽管这样做的工作量超出了必要,因为每个元素都是首先默认构造的,然后再次分配给新值。

答案 2 :(得分:12)

在这种情况下,DRY principle可以帮助您理解错误。

  

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)

或者,如果元素是一些复制昂贵的类型,则可以使用对元素的引用,甚至可以使用auto类型的引用:

for(auto& x : v)

这种新的for循环语法称为range-based for loop

答案 3 :(得分:5)

您可以认为vector是C / C ++中原始数组的灵活版本。初始化大小为vector的{​​{1}}时,构造的n的大小为vector(或者在内存中可能更大,但是您不知道,因为它是隐式的由编译器处理)。请注意,这里n代表条目数,但不代表实际的内存使用量(即字节)。如果不使用size参数对其进行初始化,则n为空,大小为0,但在内存中将具有一些隐式的默认内存大小。

假设您当前的vector的大小为5。您想在另一个元素中vector,那么push_back()将在内部将整个数组重新分配到一个新的内存位置,该位置可以容纳它的所有旧条目加上新条目。因此,您无需像C语言中那样手动手动重新分配内存。

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

1)您可以在不指定大小的情况下初始化vector。然后插入所需的每个元素。

vector

2)您可以使用该size参数以自己的方式初始化vector<int> v; for (int i = -1; i >= -5; --i) { v.push_back(i); } 。然后为它们分配新的值。

vector

3)您也可以在构造vector<int> v(5); for (int i = 0; i < v.size(); ++i) { v[i] = -i; } 时使用这些条目对其进行初始化。

vector

答案 4 :(得分:0)

使用

声明矢量时
std::vector<int> v(5);

您使v在内存中存储了5个4字节的空间(假设系统上int = 4字节),并且默认情况下,所有这些4字节的空间都存储表示0的位。然后,您通过以下命令将5个整数(-1,-2,-3,-4,-5)推入向量的末端:

v.push_back(-1);
v.push_back(-2);
v.push_back(-3);
v.push_back(-4);
v.push_back(-5);

这时向量有10个元素,前五个是在运行程序的实例上恰好存储0的未知整数。因为您的for循环会打印向量中的前五个元素,所以这就是为什么它会打印所有0的原因。

答案 5 :(得分:0)

当你声明这行 vector<int>v(5) 时,它创建了一个大小为 5 的向量,所有元素的默认值都是 0,在这个阶段你的向量看起来像这样 - {0, 0, 0, 0, 0}

现在,当您调用 v.push_back(-1) 时,它所做的是将 -1 推到向量的后面以增加其大小,现在您的向量看起来像这样 - {0, 0, 0, 0, 0, -1}

每次推回执行后,您的最终向量将是 - {0, 0, 0, 0, 0, -1, -2, -3, -4, -5}

您的向量的大小现在从 5 增加到 10,当您从索引 0 循环到 4 时,它只打印 0。我希望我解释得很好,并且在以前的答案中已经提供了解决方法。