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

时间:2012-12-28 02:13:37

标签: c# c++ c loops infinite-loop

  

可能重复:
  for ( ; ; ) or while ( true ) - Which is the Correct C# Infinite Loop?
  Why choosing for (;;){} over while(1)?

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

1 个答案:

答案 0 :(得分:10)

编译程序后没有任何区别。

以下是三个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)发出警告,因为条件始终为真,但可以轻松禁用此类警告,并且不会对生成的程序集产生任何影响。