6

重複の可能性:
for(;;)またはwhile(true)-正しいC#無限ループはどれですか?
while(1)ではなく(;;){}を選択するのはなぜですか?

while(true)、、、while(1)の違いは何for(;;)ですか?これらはすべて、C#やC /C++などの言語では無限ループです。しかし、一方はもう一方よりも優れていますか?何か案は?

4

1 に答える 1

14

プログラムがコンパイルされると、違いはありません。

これは、3つの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)。

しかし、人々は意見を持っており、何らかの理由で他の人よりも一方を好む可能性があります。は7文字しかないのでfor(;;)、入力しやすいです(これが私の好みです)。一方、while(1)は、常にに評価されるテストの錯覚を与えますtrue。これは、より直感的に感じる場合があります。gotoソリューションが一番好きなクレイジーな人はごくわずかです。

編集:条件が常に真であるため、一部のコンパイラは警告を生成する可能性がありwhile(1)ますが、そのような警告は簡単に無効にでき、生成されたアセンブリには影響しません。

于 2012-12-28T02:16:46.533 に答える