while(true) / while(1) vs. for(;;)

6

请参考https://dev59.com/Z3M_5IYBdhLWcg3wZSE6?rq=1。注意答案表明c#编译器会将`for`转换为`while`。 - Tim M.
而对于C ++,为什么选择for而不是while(1)?http://stackoverflow.com/questions/13545237/why-choosing-for-over-while1 - jogojapan
请参考 这个这个这个 或者 这个 Stack Overflow 的讨论。 - chris
1个回答

14

程序编译后没有区别。

以下是三个C程序的摘录以及它们对应的生成汇编代码。

首先让我们尝试使用for循环:

#include <stdio.h>
int main(){
   for(;;)
      printf("This is a loop\n");
   return 0;
}

现在我们将尝试使用 while 循环:

#include <stdio.h>
int main(){
   while(1)
      printf("This is a loop\n");
   return 0;
}

一个可怕的解决方案,goto 循环:

#include <stdio.h>
int main(){
   alpha:
      printf("This is a loop\n");
      goto alpha;
   return 0;
}

现在,如果我们检查生成的程序集,使用命令gcc -S loop.c,它们都是这个样子的(我没有看到任何理由将它们单独发布,因为它们是相同的):

   .file "loop.c"
   .section .rodata
.LC0:
   .string  "This is a loop"
   .text
.globl main
   .type main, @function
main:
   leal  4(%esp), %ecx
   andl  $-16, %esp
   pushl -4(%ecx)
   pushl %ebp
   movl  %esp, %ebp
   pushl %ecx
   subl  $4, %esp
.L2:
   movl  $.LC0, (%esp)
   call  puts
   jmp   .L2
   .size main, .-main
   .ident   "GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"
   .section .note.GNU-stack,"",@progbits

这部分是循环。它声明了一个标签,将字符串的地址复制到一个寄存器中,调用名为puts的例程,然后跳回到标签:

.L2:
   movl  $.LC0, (%esp)
   call  puts
   jmp   .L2

因为它们都能做同样的事情,所以显然没有任何技术上的优势(至少如果你使用的是gcc)。

然而,人们有自己的观点,可能出于各种原因更喜欢其中的一种。由于for(;;)只有七个字符长,更容易输入(这是我的偏好)。另一方面,while(1)给人一种测试条件总是评估为true的错觉,某些人可能会发现更直观。只有极少数疯狂的人最喜欢goto解决方案。

编辑:显然,一些编译器可能会对while(1)产生警告,因为条件总是为真,但这样的警告可以很容易地禁用,并不影响生成的汇编代码。


5
@Cheersandhth.-Alf 我想你说得有道理。我使用的是gcc,它不会发出这样的警告。也许我会在Visual Studio中试试。我使用生成的汇编代码来支持我的观点,即所有这些创建无限循环的方式都完全相同,因为我认为这样的声明应该有确凿的证据支持,而不是凭空捏造。 - ctype.h
我听说过编译器可能会警告 while (1),因为条件始终为真,而不会警告 for (;;),因为没有(显式的)条件。 - Keith Thompson

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