VC++ 6中“for循环”的终止条件是不是刷新?

Posted

技术标签:

【中文标题】VC++ 6中“for循环”的终止条件是不是刷新?【英文标题】:Does the termination condition of a 'for loop' refresh in VC++ 6?VC++ 6中“for循环”的终止条件是否刷新? 【发布时间】:2009-02-12 16:08:32 【问题描述】:
for (int i = 0 ; i < stlVector.size() ; i++)
 
    if (i == 10)
     
        stlVector.erase(stlVector.begin() + 5 )
    

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

提前谢谢!

最好的问候,

正音

【问题讨论】:

嗨 Ismael,你是对的,我可以只运行调试器,但我在飞行中,我没有装有 VC++ 的电脑。在机上下载东西非常昂贵,我不知道我的酒店是否可以上网。想在我可以上网的时候解决这个问题,这样我就可以睡个好觉了。 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

是的!

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

因此,对于每个循环,您都将重新评估测试“i

【讨论】:

【参考方案3】:

是的,每个循环都会执行测试,但有副作用。

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++;

-亚当

【讨论】:

这里值得一提的是,作用域有细微差别——int iwhile 示例中的循环之后可用,而在for 示例中它仅限于循环作用域。 【参考方案4】:

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

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

【讨论】:

实际上,如果你再读一遍:他并没有擦除第 i+5:th 个元素。而且我相信检查“if (i == 10)”(连同循环条件)基本上保证元素 begin()+5 存在,不是吗?此外,使用迭代器不是比您建议的辅助向量解决方案更好吗? 您对元素检查和迭代器的使用是正确的。我认为这个例子只是“幻想代码”,只是想指出一个常见的错误(使用索引指向一个在循环内被改变的向量中的元素)。【参考方案5】:

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

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

【讨论】:

【参考方案6】:

总是重新评估确定!

【讨论】:

【参考方案7】:

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

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

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

【讨论】:

是的,VC++6 肯定坏了。我不能说它是否以这种特定方式被破坏,但它肯定以无数其他方式被破坏。 我只是想...也许 OP 实际上知道这一切并且只是令人难以置信的讽刺? :) 也许他的下一个问题是“VC++6 中的 2+2==4 吗?” :-P 其实不是讽刺……只是谨慎。 VC++ 6 永远不会让我惊讶。【参考方案8】:

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

int saveSize = someExpensiveComputation();

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

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

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

循环中的每次迭代都不必要地进行昂贵的计算。

【讨论】:

在一个像样的编译器上,这并不会真正让任何事情变得更快。因为 std::vector 中的 size() 是 O(1) (标准是这样说的)。该调用将被内联,并且矢量对象的位置不会在循环中更改。所以你正在用一个内存引用换另一个...... 如果您对其进行测试,您会发现生成的程序集通常是相同的(或功能相同) 是的,这就是为什么我说“循环条件的计算成本很高”。我不想完全重写他的例子来表达我的观点。【参考方案9】:

是的,它减小了尺寸。更多信息是here

【讨论】:

以上是关于VC++ 6中“for循环”的终止条件是不是刷新?的主要内容,如果未能解决你的问题,请参考以下文章

java中的for循环

c语言 for循环次数

for循环是否由于无符号int溢出而终止?

for 循环与嵌套

JavaScript中的循环

部分循环语句书写格式