调用以条件循环(c++)

call to condition on for loop (c++)

本文关键字:c++ 循环 条件 调用      更新时间:2023-10-16

这里有一个我想了很久的简单问题:当我做这样的循环时:

for (int i = 0; i < myVector.size() ; ++i) {
// my loop
}

由于每次都检查条件i < myVector.size(),我是否应该在循环之前将数组的大小存储在变量中,以防止每次迭代都调用size()?或者编译器是否足够聪明,可以自己完成?

mySize = myVector.size();   
for (int i = 0; i < mySize ; ++i) {
// my loop
}

我会用一个更复杂的条件来扩展这个问题,比如i < myVector.front()/myVector.size()

编辑:我不在循环中使用myVector,它只是在这里给出结束条件。更复杂的情况呢?

答案主要取决于循环的内容——它可能会在处理过程中修改向量,从而修改其大小。

但是,如果只是扫描矢量,您可以提前安全地存储其大小:

for (int i = 0, mySize = myVector.size(); i < mySize ; ++i) {
// my loop
}

尽管在大多数类中,像"获取当前大小"这样的函数只是内联getter:

class XXX
{
public:
int size() const { return mSize; }
....
private:
int mSize;
....
};

因此编译器可以很容易地将调用减少为只读取int变量,因此预取长度不会带来任何增益。

如果在for循环(这是正常情况)期间不更改矢量中的任何内容(添加/删除),我会使用foreach循环

for (auto object : myVector)
{
//here some code
}

或者,如果你不能使用c++11,我会使用迭代器

for (auto it = myVector.begin(); it != myVector.end(); ++it)
{
//here some code
}

我想说

for (int i = 0; i < myVector.size() ; ++i) {
// my loop
}

比安全一点

mySize = myVector.size();   
for (int i = 0; i < mySize ; ++i) {
// my loop
}

因为myVector.size()的值可能会改变(例如循环中的push_back(value)),因此您可能会错过一些元素
如果您100%确信myVector.size()的值不会改变,那么两者都是一样的
然而,第一个比第二个更灵活(其他开发人员可能不知道循环在固定大小上迭代,他可能会更改数组大小)。别担心编译器,他比我们两个加起来都聪明。

开销非常小。vector.size()不会重新计算任何内容,只是简单地返回私有大小变量的值。。

它比预缓冲值更安全,因为当元素被弹出或推送到向量或从向量中推出来时,向量内部大小变量会发生变化。。

编译器可以被编写来优化这一点,如果并且只有当,它可以预测在for循环运行时,矢量不会被任何东西改变。如果里面有线程,那就很难做到。

但是如果没有任何线程,优化它是非常容易的。

任何智能编译器都可能对此进行优化。然而,为了确保我通常会这样布置for循环:

for (int i = myvector.size() -1; i >= 0; --i)
{
}

有几点不同:

  • 迭代是以另一种方式完成的。尽管在大多数情况下这不应该是个问题。如果是的话,我更喜欢大卫·海姆的方法。

  • 使用了--i而不是i-。理论上,--i更快,尽管在大多数编译器上它不会有什么不同。

如果你不关心这个索引:

for (int i = myvector.size(); i > 0; --i)
{
}

也可以选择。尽管一般来说我不使用它,因为它比第一个更令人困惑。不会给你带来任何表现。

对于像std::vectorstd::list这样的类型,迭代器是首选方法:

for (std::vector</*vectortype here*/>::iterator i = myVector.begin(); i != myVector.end(); ++i)
{
}