1

例如:

 vector<int> something;
 //imagine i add some elements to the vector here

 int* pointy;
 for (int i = 0; i < something.size(); pointy = &something[i++]) {
      //do some work with pointy
 }

它似乎有效并为我节省了一条线,但是否有任何奇怪的错误因此而出现的危险?

4

5 回答 5

13

这可能不合法,因为pointy在第一次迭代时未分配。如果循环在初始迭代期间没有取消引用pointy,那可能是可以的,但不看循环体就无法判断。

由于您正在使用std::vector,因此使用迭代器将为您节省另一行,因为您不需要声明pointy. 您无需从当前迭代器i中减去即可确定偏移量:something.begin()

for (vector<int>::iterator iter = something.begin() ; iter != something.end() ; ++iter) {
    cout << "Item at index " << (iter - something.begin()) << " is " << *iter << endl;
}
于 2013-06-02T11:58:24.613 回答
6

是的,正如 dasblinkenlight 指出的那样,这很危险。但是有一种更简单的方法可以消除这类问题。

首先为简单和可读性编写代码。将循环压缩到尽可能少的行数不会在性能方面增加任何东西,即使这样做了,只要探查器没有告诉您循环是瓶颈,您也不应该在意。

另一方面,它会使您的代码更难阅读,并且可能更容易出现错误(正如您可能已经注意到的那样)。

在 C++11 中,考虑使用基于范围的for循环:

for (int& p : something)
{
   // ...
}

在 C++03 中,考虑使用std::for_each(), 或基于迭代器的经典循环:

for (std::vector<int>::iterator i = something.begin(); i != something.end(); ++i)
{
    // use *i to refer to the current pointy
    // use (i - something.begin()) to get its index
    // ...
}
于 2013-06-02T11:59:38.947 回答
1

这是非常危险的,因为i不是unsigned。在极少数情况下它可能会爆炸。:)

于 2013-06-02T12:02:38.253 回答
0

这是否安全真的取决于你所追求的。pointy 将是指向向量中元素的指针。这意味着,如果您更改 pointy 的值,或者将其指向更具体的内容,您实际上是在更改该特定元素的向量内容。

于 2013-06-02T12:01:46.847 回答
0

至于我,我喜欢像这样处理更大的对象的 std::vector :

std::vector<int*> mynumbers;
//add elements here like this:
int somenumber = 5;
mynumbers.push_back(&somenumber);

for(int i=0;i<elemnts.size();i++)
{
    cout << "Element Nr. " << i << ": " << *elements.at(i) << endl;
    //modify like this:
    *elements.at(i) = 0;
}

指针而不是变量本身是因为 std::vector 比大对象本身更快地处理指针,但是对于 int,这并没有太大的区别,所以你也可以这样做:

std::vector<int> mynumbers;
mynumbers.push_back(5);

int* pointy
for(int i=0;i<elemnts.size();i++)
{
    pointy = &elements.at(i);
}

对我有用!

于 2013-06-02T12:39:13.377 回答