无限while循环和for循环有什么区别?

6

我看到许多书籍中使用的不同惯例,其中您可以使用以下任一循环结构创建无限循环:

while()
   foo();
for(;;)
   foo();

但是,实际上,我应该了解哪些差异?哪一个更好?

6个回答

7
它们在语义上是等价的。(x;y;z) { foo; } 等价于 x; while (y) { foo; z; }。在标准的进一步版本中,它们并不完全等价,例如 for (int x = 0; y; z) 的情况下,x 的作用域是 for 块,在循环结束后就超出了作用域,而使用 int x; while (y) x 则在循环结束后仍然在作用域内。
另一个区别是,for 将缺少的 y 解释为 TRUE,而 while 必须提供表达式。 for (;;) { foo; } 是可以的,但 while() { foo; } 不行。

2
请注意,问题是关于无限循环的,而不是一般情况下for和while语句的语义。 - Ben Zotto
3
如果您想在语句“x”的范围内进行操作,您可以说for (x; y; z) { foo; }等同于{ x; while (y) { foo; z; } } - Jon Purdy
就语义而言,C语言标准的for循环允许构建与while循环相同的for循环。然而,这与更深层次的for循环语义理解相冲突,后者不可避免地包含循环变量(通常为正数,出于方便起见)。为了保持一致的语义,应该明确区分在执行循环之前已知迭代计数的循环(for循环)和在执行之前未知迭代计数的循环(while循环)。 - Schedler
你的回答不准确。"(int x = 0; y; z)",x的作用域是for循环块,在循环结束后超出作用域,在所有版本中都是正确的。"int x; while (y) x"(语法错误),并且在所有版本中将具有while父级的局部性。因此,那部分内容并没有完全准确地命中要点。 - iantonuk

2

我在VS2010调试模式下看到一个小差别。不确定它是否足以被视为在所有编译器和所有优化情况下都是重要和普遍正确的差异。

所以从概念上讲,这些循环是相同的,但在处理器级别上,对于无限消息循环,附加/不同指令的时钟周期可能会不同,从而产生一些差异。

   while(1)
004113DE  mov         eax,1                       **// This is the difference**
004113E3  test        eax,eax                     **// This is the difference**
004113E5  je          main+2Eh (4113EEh)  
      f();
004113E7  call        f (4110DCh)  
004113EC  jmp         main+1Eh (4113DEh)          **// This is the difference**
   for(;;)
      f();
004113EE  call        f (4110DCh)  
004113F3  jmp         main+2Eh (4113EEh)          **// This is the difference**
} 

2
启用任何优化后,这种差异绝对不存在。 - Ben Voigt
区别仅在于调试模式默认关闭了优化。实际上,前三行代码是在检查1 != 0,即条件是否为真。 - casablanca
而在jmp中的差异只是一个稍微不同的偏移量。 - tc.
我喜欢你的方法。那是真实类型的答案,但我宁愿在代码中添加更多的汇编代码,并在行上加注释。for循环中有很多事情要做。for(;;)的反汇编代码永远不会反映出来,因为你的编译器优化了它,这就破坏了整个目的。(例如while(0){..}将被优化为空)。 - iantonuk

1

没有区别。

但是

while() foo();

不同于

for(;;foo();)

记住!如果在foo()语句之前中断while循环,foo()不会执行,但是如果在for循环中断,foo()会执行...


1

1
很好的发现,与其他问题相似。 - Nullw0rm

0

它们都是相同的... 现代编译器为两者发出相同的代码... 有趣的是(历史上?) for(;;) 更受欢迎... Pascal程序员曾经使用 #define (;;), 并使用 forever {//code}。


0
第一个代码无法编译。你至少需要:while( true )。它们在语义上是等价的,这只是一种风格/个人选择的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接