重複の可能性:
for(;;)またはwhile(true)-正しいC#無限ループはどれですか?
while(1)ではなく(;;){}を選択するのはなぜですか?
while(true)
、、、while(1)
の違いは何for(;;)
ですか?これらはすべて、C#やC /C++などの言語では無限ループです。しかし、一方はもう一方よりも優れていますか?何か案は?
重複の可能性:
for(;;)またはwhile(true)-正しいC#無限ループはどれですか?
while(1)ではなく(;;){}を選択するのはなぜですか?
while(true)
、、、while(1)
の違いは何for(;;)
ですか?これらはすべて、C#やC /C++などの言語では無限ループです。しかし、一方はもう一方よりも優れていますか?何か案は?
プログラムがコンパイルされると、違いはありません。
これは、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)
ますが、そのような警告は簡単に無効にでき、生成されたアセンブリには影響しません。