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

发布于 2024-08-28 23:40:05 字数 307 浏览 1 评论 0原文

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

现在,例如,如何将向量的第 5 个元素更改为 -1

我尝试了 l.assign(4 ,-1); 它的行为不符合预期。其他矢量方法似乎都不适合。

我使用了向量,因为我需要在代码中使用随机访问功能(使用 l.at(i))。

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?

I tried 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)).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

晌融 2024-09-04 23:40:05

atoperator[] 都返回对索引元素的引用,因此您可以简单地使用:

l.at(4) = -1;

l[4] = -1;

at and operator[] both return a reference to the indexed element, so you can simply use:

l.at(4) = -1;

or

l[4] = -1;
泪是无色的血 2024-09-04 23:40:05

尽管@JamesMcNellis 的答案是有效的,但我想解释一些有关错误处理的内容,以及还有另一种方法可以做你想做的事情这一事实。

有四种方法可以访问向量中的特定项:

  • 使用 [] 运算符
  • 使用成员函数 at(...)
  • 使用迭代器与给定的组合offset
  • 使用标准 C++ 库的 algorithm 标头中的 std::for_each。这是我可以推荐的另一种方法(它在内部使用迭代器)。您可以在此处阅读更多相关信息。

在下面的示例中,我将使用以下向量作为实验老鼠并解释前三种方法:

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

这将创建一个向量,如下所示:

1 2 3 4

首先让我们看看 [] 的处理方式。它的工作方式与您使用普通数组时所期望的方式几乎相同。您提供一个索引,可能您可以访问您想要的项目。我说可能是因为[]运算符不会检查向量是否确实有那么多项目。这会导致无提示的无效内存访问。示例:

v[10] = 9;

这可能会也可能不会导致立即崩溃。最糟糕的情况当然是如果没有,而您实际上得到了看似有效的值。与数组类似,这可能会导致浪费时间来尝试查找原因,例如 1000 行代码之后您会得到 100 而不是 234 的值,这有点连接到您从向量中检索项目的位置。

更好的方法是使用 at(...)。这将自动检查越界行为并中断抛出std::out_of_range。因此,当我们有的情况下,

v.at(10) = 9;

我们将得到:

抛出“std::out_of_range”实例后调用终止
What(): vector::_M_range_check: __n (即 10) >= this->size()
(即 4)

第三种方法类似于 [] 运算符,从某种意义上说,您可以把事情搞砸。向量就像数组一样,是包含相同类型数据的连续内存块的序列。这意味着您可以通过将起始地址分配给迭代器来使用它,然后只需向该迭代器添加偏移量即可。偏移量仅代表您要遍历的第一个项目之后的项目数量:

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
// ...

如您所见,我们也可以这样做

*(it+10) = 9;

,这又是一次无效的内存访问。这与使用 at(0 + offset) 基本相同,但没有越界错误检查。

我建议尽可能使用 at(...) ,不仅因为它比迭代器访问更具可读性,而且因为我上面提到的针对带有偏移量的迭代器的无效索引的错误检查组合和 [] 运算符。

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.

You have four ways of accessing a specific item in a vector:

  • Using the [] operator
  • Using the member function at(...)
  • Using an iterator in combination with a given offset
  • Using std::for_each from the algorithm header of the standard C++ library. 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.

A much better way is to use at(...). This will automatically check for out of bounds behaviour and break throwing an 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'
what(): vector::_M_range_check: __n (which is 10) >= this->size()
(which is 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.

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.

唱一曲作罢 2024-09-04 23:40:05

这应该可以做到:

l[4] = -1

This should do it:

l[4] = -1
感性不性感 2024-09-04 23:40:05

您可以使用下标运算符

l[4] = -1

You can use the subscript operator

l[4] = -1
独闯女儿国 2024-09-04 23:40:05

我更喜欢

l.at(4)= -1;

[4] 是你的索引

I prefer

l.at(4)= -1;

while [4] is your index

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文