简体   繁体   English

如何更改C ++ STL向量的特定元素

[英]How to change a particular element of a C++ STL vector

vector<int> l;
for(int i=1;i<=10;i++){
   l.push_back(i);
}

Now, for example, how do I change the 5th element of the vector to -1 ? 现在,例如, 如何将向量的5th element更改为-1

I tried l.assign(4, -1); 我试过l.assign(4, -1); It is not behaving as expected. 它的行为不符合预期。 None of the other vector methods seem to fit. 其他矢量方法似乎都不合适。

I have used vector as I need random access functionality in my code (using l.at(i) ). 我使用了矢量,因为我需要在我的代码中使用随机访问功能(使用l.at(i) )。

at and operator[] both return a reference to the indexed element, so you can simply use: atoperator[]都返回对索引元素的引用,因此您可以简单地使用:

l.at(4) = -1;

or 要么

l[4] = -1;

Even though @JamesMcNellis answer is a valid one I would like to explain something about error handling and also the fact that there is another way of doing what you want. 尽管@JamesMcNellis的答案是有效的,但我想解释一些关于错误处理的事情,以及还有另一种方法可以做你想做的事情。

You have four ways of accessing a specific item in a vector: 您有四种方法可以访问向量中的特定项:

  • Using the [] operator 使用[]运算符
  • Using the member function at(...) 使用at(...)的成员函数
  • Using an iterator in combination with a given offset 将迭代器与给定的偏移量结合使用
  • Using std::for_each from the algorithm header of the standard C++ library. 使用标准C ++库的algorithm头中的std::for_each This is another way which I can recommend (it uses internally an iterator). 这是我可以推荐的另一种方式(它在内部使用迭代器)。 You can read more about it for example here . 您可以在此处阅读有关它的更多信息。

In the following examples I will be using the following vector as a lab rat and explaining the first three methods: 在下面的例子中,我将使用以下载体作为实验室大鼠并解释前三种方法:

static const int arr[] = {1, 2, 3, 4};
std::vector<int> v(arr, arr+sizeof(arr)/sizeof(arr[0]));

This creates a vector as seen below: 这会创建一个向量,如下所示:

1 2 3 4

First let's look at the [] way of doing things. 首先让我们来看看[]的做事方式。 It works in pretty much the same way as you expect when working with a normal array. 它的工作方式与使用普通数组时的预期方式大致相同。 You give an index and possibly you access the item you want. 您提供索引并可能访问所需的项目。 I say possibly because the [] operator doesn't check whether the vector actually has that many items. 我说可能是因为[]运算符不检查向量是否实际上有那么多项。 This leads to a silent invalid memory access. 这导致无声的无效内存访问。 Example: 例:

v[10] = 9;

This may or may not lead to an instant crash. 这可能会也可能不会导致即时崩溃。 Worst case is of course is if it doesn't and you actually get what seems to be a valid value. 最糟糕的情况当然是如果它没有,你实际上得到的似乎是一个有效的值。 Similar to arrays this may lead to wasted time in trying to find the reason why for example 1000 lines of code later you get a value of 100 instead of 234 , which is somewhat connected to that very location where you retrieve an item from you vector. 与数组类似,这可能会导致浪费时间试图找到原因,例如1000行代码后来得到的值为100而不是234 ,这有点连接到从向量中检索项目的位置。

A much better way is to use at(...) . 更好的方法是使用at(...) This will automatically check for out of bounds behaviour and break throwing an std::out_of_range . 这将自动检查out of bounds行为并中断抛出std::out_of_range So in the case when we have 所以在我们拥有的情况下

v.at(10) = 9;

We will get: 我们将得到:

terminate called after throwing an instance of 'std::out_of_range' 抛出'std :: out_of_range'实例后调用终止
what(): vector::_M_range_check: __n (which is 10) >= this->size() (which is 4) what():vector :: _ M_range_check:__n(10)> = this-> size()(4)

The third way is similar to the [] operator in the sense you can screw things up. 第三种方式类似于[]运算符,你可以搞砸了。 A vector just like an array is a sequence of continuous memory blocks containing data of the same type. 像数组一样的向量是包含相同类型数据的连续内存块序列。 This means that you can use your starting address by assigning it to an iterator and then just add an offset to this iterator. 这意味着您可以通过将起始地址分配给迭代器来使用起始地址,然后只需向此迭代器添加偏移量。 The offset simply stands for how many items after the first item you want to traverse: 偏移量仅表示要遍历的第一个项目后的项目数:

std::vector<int>::iterator it = v.begin(); // First element of your vector
*(it+0) = 9;  // offest = 0 basically means accessing v.begin()
// Now we have 9 2 3 4 instead of 1 2 3 4
*(it+1) = -1; // offset = 1 means first item of v plus an additional one
// Now we have 9 -1 3 4 instead of 9 2 3 4
// ...

As you can see we can also do 如你所见,我们也可以做到

*(it+10) = 9;

which is again an invalid memory access. 这又是一个无效的内存访问。 This is basically the same as using at(0 + offset) but without the out of bounds error checking. 这基本上与使用at(0 + offset)但没有越界错误检查相同。

I would advice using at(...) whenever possible not only because it's more readable compared to the iterator access but because of the error checking for invalid index that I have mentioned above for both the iterator with offset combination and the [] operator. 我建议尽可能使用at(...)不仅因为它与迭代器访问相比更具可读性,而且因为我对上面提到的带偏移组合的迭代器和[]运算符的无效索引进行了错误检查。

这应该这样做:

l[4] = -1

您可以使用下标运算符

l[4] = -1

I prefer 我更喜欢

l.at(4)= -1;

while [4] is your index 而[4]是你的指数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM