0
for (int i = 0 ; i < stlVector.size() ; i++)
{ 
    if (i == 10)
    { 
        stlVector.erase(stlVector.begin() + 5 )
    }
}

终止条件部分“stlVector.size()”是否考虑了“stlVector.erase(...)”?换句话说,每次循环迭代都会刷新 stlVector.size() 吗?我现在无法测试它,所以我在这里发布了一个问题。

提前谢谢!

最好的祝福,

正补

4

9 回答 9

5

为了清楚起见,不要从循环刷新任何东西的角度来考虑它。每次检查条件时(在每次循环开始时),都会在 stlVector 变量上调用 size() 方法,并返回向量的当前大小。

erase() 方法减小了向量的大小,所以下次调用 size() 时,返回的值会更小。

于 2009-02-12T16:22:48.023 回答
4

是的,它确实!

stlVector.size () // is called for evey iteration

因此,对于每个循环,您都将重新评估测试“i < stlVector.size ()”!

于 2009-02-12T16:13:55.707 回答
4

是的,对每个循环都进行了测试,但有副作用。

for 循环只是一个很好的约定 - for 循环很容易分解为 while 循环:

for (int i = 0 ; i < stlVector.size() ; i++)
{ 
    if (i == 10)
    { 
        stlVector.erase(stlVector.begin() + 5 )
    }
}

变成:

int i = 0 ;

while(i < stlVector.size())
{ 
    if (i == 10)
    { 
        stlVector.erase(stlVector.begin() + 5 )
    }
    i++;
}

-亚当

于 2009-02-12T16:14:27.030 回答
3

是的,确实如此,但不要这样做!如果要从向量中删除元素,请在另一个循环中执行。在这种情况下,您将删除 i 索引之后的元素:没有任何东西可以保证 stlVector[i+5] 元素存在。如果你从向量中删除第 i 个元素,你的计数就会被破坏,因为你可以在不检查元素的情况下跳转元素。

最安全的方法是将要删除的 stlVector 上的元素的引用存储在另一个向量上,然后在此辅助向量上执行 stlVector.erase(auxVector[i]) 进行迭代。

于 2009-02-12T16:29:05.217 回答
2

我希望您提供的代码只是“幻想代码”(正如一位评论者所说),以给出您正在尝试做的事情类型的具体示例。

但是以防万一:您给出的循环将跳过第 12 个元素(即最初在 中的元素stlVector[11]),因为在检查stlVector[10]时删除了较早的元素,导致所有后面的元素向前分流一个位置,但您仍然i在最后增加的循环。因此,下一次迭代将查看stlVector[11]哪个元素实际上是最初在stlVector[12]. 要解决此问题,您需要--i在调用erase().

于 2009-02-13T08:11:31.333 回答
2

总是重新评估确定!

于 2009-02-14T11:01:53.677 回答
1

另外,澄清一下,因为您询问是否“在 VC++ 6 中”以这种方式完成。

“继续条件”在每个版本的 C、C++、C# 和 Java 中的每个循环上重新评估。

如果任何编译器不生成执行此操作的代码,则它已损坏,必须避免。

于 2009-02-12T16:33:21.213 回答
1

正如其他人所说,是的,每次通过循环都会重新评估条件。这就是为什么一个常见的性能优化是:

int saveSize = someExpensiveComputation();

for (int i = 0 ; i < saveSize ; i++)
{ 
    foo(i);
}

其中循环条件的计算成本很高,而不是

for (int i = 0 ; i < someExpensiveComputation(); i++)
{ 
    foo(i);
}

在循环中每次迭代都不必要地完成昂贵的计算。

于 2009-02-12T16:40:25.657 回答
0

是的,它减小了尺寸。更多信息在这里

于 2009-02-12T16:14:49.900 回答