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

4 c c# c++ loops infinite-loop

可能重复:
for(;;)或while(true) - 哪个是正确的C#无限循环?
为什么选择(;;){}而不是(1)?

什么之间的区别while(true),while(1)以及for(;;)?它们都是C#和C/C++等语言中的无限循环.但是一个比另一个好吗?有任何想法吗?

cty*_*e.h 12

程序编译后没有区别.

以下是三个C程序的摘录以及所有这些程序的相应生成程序集.

让我们for先尝试循环:

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

现在我们将尝试while循环:

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

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

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

现在,如果我们使用命令检查生成的程序集,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
Run Code Online (Sandbox Code Playgroud)

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

.L2:
   movl  $.LC0, (%esp)
   call  puts
   jmp   .L2
Run Code Online (Sandbox Code Playgroud)

由于它们都完全相同,显然它们中没有任何技术优势(至少如果你使用的话gcc).

然而,人们有意见,并且无论出于何种原因,他们可能会偏袒其他人.由于for(;;)只有七个字符长,因此更容易输入(这是我的偏好).另一方面,while(1)给出了总是评估的测试的错觉true,有些人可能会发现更直观.只有少数疯狂的人喜欢goto最好的解决方案.

编辑:显然,某些编译器可能会生成警告,while(1)因为条件始终为true,但可以轻松禁用此类警告,并且不会对生成的程序集产生任何影响.

  • @ Cheersandhth.-Alf我想你有一点意见.我正在使用`gcc`,它没有发出这样的警告.也许我会在Visual Studio中尝试它.我使用生成的程序集来支持我声称所有这些创建无限循环的方法完全相同的事情,因为我觉得这样的声明应该由坚实的证据支持,而不是从无处撤出. (4认同)