这是合法使用for循环吗?

时间:2013-06-02 11:55:50

标签: c++

例如:

 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
 }

它似乎工作并为我节省了一条线,但是因为这个,是否有任何奇怪的错误突然出现在线上?

5 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:6)

是的,这很危险,as dasblinkenlight pointed out。但是有一种更简单的方法来消除这种问题。

首先编写代码以简化和可读性。将循环压缩到尽可能少的行数不会增加任何性能,即使它确实如此,只要你的分析器没有告诉你循环是一个瓶颈,你就不应该在意。

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

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

答案 2 :(得分:1)

这非常危险,因为i不是unsigned。在一些罕见的情况下它会爆炸。 :)

答案 3 :(得分:0)

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

答案 4 :(得分: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);
}

非常适合我!