我制作了一个恒定大小的矢量来存储负值,然后打印所有我得到的值都是零。我只想知道为什么它不存储负值。
#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
}
答案 0 :(得分:53)
这是因为push_back
将 new 元素放在向量的末尾。
通过将i
到9
可以看到效果:负数将占据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。我希望我解释得很好,并且在以前的答案中已经提供了解决方法。