for(;;)またはwhile(true)の正しいC#無限ループはどれですか?[閉まっている]


97

C / C ++時代に戻って、「無限ループ」を次のようにコーディングします。

while (true)

とは対照的に、私はより自然に感じ、私にはより明白に見えた

for (;;)

1980年代後半のPC lintとの出会いとその後のベストプラクティスの議論は、私がこの習慣を破った。それ以来、for制御ステートメントを使用してループをコーディングしました。今日、久しぶりに、そしておそらくC#開発者として無限ループが初めて必要になったとき、私は同じ状況に直面しています。それらの1つは正しく、もう1つは正しくありませんか?


5
2分以内に4つの同じ答え。悪くない。
Jon B

5
無限ループを展開することで、宗教的な議論全体を回避できます。時間はかかりません...
スティーブンダーリントン

7
好奇心から抜け出して:C / C ++ではfor(;;)の方が優れているのはなぜですか?
Vilx- 2009

6
@Vilxを思い出すと、古いコンパイラは、while(1)よりもfor(;;)を使用した方が効率的なコードを記述していた。きちんとした最新のコンパイラは、ほとんど同じコードを出力するはずです。
スティーブンダーリントン

4
スティーブンとセルヒオのコメントを基にして:1 while(true).条件が必要です。for(;;)したがって、無条件に繰り返す無限ループのより適切な表現です。2.古い最適化されていないコンパイラは(true)、ループしたとおりに実際にを評価した可能性があります。3. Cは、テレタイプ、300ボー端末、および1文字の変数名の時代のミニマリスト言語です。すべてのキーストロークがカウントされる環境では、for(;;)はに比べてかなり短いですwhile(true)
Richard Dingwall、2011年

回答:


124
while(true)
{

}

常に私が使用したものであり、手動で中断しなければならないループに他の人が使用しているのを見てきました。


@RSolberg-数秒以内に提供された2つの類似した応答の間のトスアップでした。Adamのフォローアップコメントにより、私は慣習ではなく使用法に基づいた回答を受け入れるようになりました。
Bob Kaufman

1
whileとforはどちらも手動
Allen Rice

2
残念ながら、この答えは質問には答えません。正解は「どちらも正しい」です。
デビッドRトリブル

2
@Loadmaster:それはあなたの「正しい」の定義に依存します(あるいは、あなたが求めている「正しい」の種類に依存します)。
アダムロビンソン

314

C#コンパイラは両方を変換します

for(;;)
{
    // ...
}

そして

while (true)
{
    // ...
}

{
    :label
    // ...
    goto label;
}

両方のCILは同じです。ほとんどの人はwhile(true)読みやすく、理解しやすいと感じています。for(;;)かなり不可解です。

ソース:

.NET Reflectorをもう少しいじって、Visual Studioで「最適化コード」を使用して両方のループをコンパイルしました。

両方のループがコンパイルされます(.NET Reflectorを使用):

Label_0000:
    goto Label_0000;

ラプターズはすぐに攻撃する必要があります。


7
うん、ちょうどダブルチェック、それはすべて同じILコードです、これは受け入れられた答えであるべきですIMO :)
アレンライス

63
xkcdリファレンスの+1
Ikke

4
簡潔にするために、コンパイラーは1つのステートメント形式を他の形式に変換しませ。むしろ、両方のステートメントに対して同一のコードを生成します。そのコードはgoto、当然のことながら、ステートメントと同じです。
David R Tribble

1
そしてその後、後藤は、JMP命令に変換され..
マルコM.

25
明らかgoto LOOPに正しいC#無限ループです:)
ダスティンゲッツ

61

これは読みやすく、間違いなくC#で使用するための標準だと思います。

while(true)
{
   //Do My Loop Stuff
}

19
@voyager:1はC#の「true」の代わりにはなりません。
アダムロビンソン

17
while(1)が無効であることに注意してくださいC#:定数1はブール値に変換できません
Vinko Vrsalovic

4
while(1)以来、C#には有効ではありません1ではありませんbool
Pavel Minaev

47

ガスプ、使用:

while (!false)
{

}

またはjsightが指摘したように、あなたは二重に確信したいかもしれません:

while (!false && true)
{
}

人々が私に怒鳴る前に、それはすべて同じCILコードです、私はチェックしました:)


史上最高の答え。
ラリー

38

いくつかの古いジョークを再ハッシュするには:

  1. for (;;) {}」を使用しないでください。ステートメントが泣きます。
  2. もちろん、 " #define EVER ;;" でない限り。

24
または#define ever (;;)私はもっ​​と読みやすいと思います。for ever {}
Chris Lutz、

1
C#で#define(;;)を実行できるとは思いませんでしたが、冗談はおかしいです:)
Allen Rice

1
ああ。OS XでCをプログラミングしています。C#プリプロセッサがそれほど去勢されていることを知りませんでした。私はこの質問をどのように読み始めたかさえわかりません。C#を無視されたタグとして使用しています...
Chris Lutz

C#プリプロセッサーは、少なくともC、C ++、PL / 1、さらにはマクロアセンブラーが提供するものに関しては、実際にはプリプロセッサーではありません。プリプロセッサシンボルを定義/定義解除することによって、コードのブロックを有効または無効にすることのみが可能です。
David R Tribble

6
またはさらに良い:#define forever while(true);)
Roberto Bonvallet 2009

26

古い学校に行きたい場合でも、C#ではgotoがサポートされています。

STARTOVER:  
    //Do something
    goto STARTOVER;

真の無限ループの場合、これはgo-toコマンドです。=)



6
私はこれを否定的な評価からゼロに戻しましたが、それはそのユーモアの価値のためです。とにかく、すべてのループがJMPアセンブラーオペコードにコンパイルされますよね?
David R Tribble

@Loadmaster:ありがとう、私はそれを別のオプションとして単にそこに捨てていたのであり、必ずしもそれを支持しているわけではない。
JohnFx 2009

2
@serhio:どこかで何かを読んだので、手に負えない言語構造を回避することはさらにそうです。言語要素自体は悪いものではなく、悪い方法でしか使用できません。
JohnFx

2
@serhio:可能な限りすべてのキーワードを使用して、自然に対する嫌悪感を見てきました。それは言語要素ではなく、プログラマーです。いずれにせよ、前のコメントで述べたように、私はそれを承認していませんでした。私は完全性とユーモアのチクチクのためにそれを含めていました。
JohnFx


10

真の無限ループが必要な状況では、私は常に使用してきました

while(true) {...}

空のforステートメントよりも意図を表現しているようです。


10

個人的にfor(;;)条件がないため(while (true)常に真条件があるのとは対照的に)、常に正確に選択しました。しかし、これは実際には非常にマイナーなスタイルのポイントであり、どちらの方法についても議論する価値はないと思います。どちらのアプローチも強制または禁止するC#スタイルのガイドラインはまだ見ていません。


.NETでは価値がありません。コンパイラーが(with bad read)無条件で変換するとき、しばらくは条件付きです。
serhio 2010

3
@serhio:「コンパイラ変換...の意味」を説明してくださいwhile。プログラマに関する限り、コンパイラは高レベルのコードをILに変換します。ILにはループwhile(またはfor)はなく、ラベルと後処理だけがあります。
Pavel Minaev

1
Pierre-Alain Vigeantの回答を参照してください。
serhio

3
彼の答えは、単に「コンパイラが両方に対して同一のILを生成する」と言い換えることができます(ASTレベルで何かを変換するかどうか、いつ変換するかは実際にはわかりません。いずれにせよ、実装の詳細です)。いずれにせよ、これが「.NETでそれだけの価値がない」理由を説明していません。同じことがC ++、Javaにも当てはまります
Pavel Minaev

6

私は個人的にfor (;;)イディオムを好みます(C / C ++の観点から)。while (true)ある意味で読みやすくなっていることには同意しますが(C / C ++の場合でも以前と同じように使用しています)、次のfor理由でイディオムを使用することにしました。

  • 目立つ

ループが(通常の方法で)終了しないという事実は、「コールアウト」する価値があると思いますfor (;;)。これにより、もう少し多くのことができると思います。


最後に、それを使用して、プログラムがコンパイルされるまで少し待ちます(for => whileからの変換のコンパイル)
serhio

3
@serhio:そうではありません。からに変換されません。との両方で、新しいコードが生成されます。この回答を参照してください。forwhilefor (;;){}while (true){}while(true){}
wchargin 2012

6

Cの祖先をたどることができる、C のオリジナルのK&Rブック、推奨

for (;;) ...

無限ループの場合。明確で読みやすく、その背後には長く高貴な歴史があります。

補遺 (2017年2月)

もちろん、このループ形式(またはその他の形式)があまりにもわかりにくいと思われる場合は、いつでもコメントを追加できます。

// Infinite loop
for (;;)
    ...

または:

for (;;)    // Loop forever
    ...

1
はい、ただし、これはC用であり、C#用ではありません。
serhio

1
C#で動作します。そして、C#言語がCから(間接的に)得た
デヴィッド・Rトリブル

4
8年後、回答を更新することにしました。ニース
メトニエム

4

それはすべきでwhile(true)はないwhile(1)のでwhile(1)、C#では正しくありません、はい;)


2

あるいは、アプリが実際に永久に実行されない限り終了条件が必要になるため、無限ループを設定することは、通常、とにかく悪い習慣であると言えます。ただし、これが巡航ミサイルの場合は、明示的な終了条件は必要ないかもしれないと認めます。

私はこれが好きですが:

for (float f = 16777216f; f < 16777217f; f++) { } 

2
-1:誰もがコードを読み取る「無限ループ」を理解するわけではありません。おそらく誰かがこれをバグであると考え、それを「修正」しようとするかもしれません...
serhio

C#f < 16777217fでは常にfalse...なので、これはループしません。
NetMage

2

私はもう少し「読みやすい」コードを好む。私は実際にこのようなことをする可能性がはるかに高いです:

bool shouldContinue = true;
while (shouldContinue)
{
    // ...

    shouldContinue = CheckSomething();
}

1
ああ。実は、それdo ... while()は変装のループです。それを見るのに数秒かかりました。あなたがdo ... while()ループを書けば、それはすぐに明らかだっただろう。-1
sbi 2009

while(true)を使用できるのに、なぜ変数と宣言に時間とリソースを浪費するのですか?それは私の意見では意味をなさない
ワカサメド09/09/09

特に、「while(!this.canceled)」などの特定の意味のあるフラグを付けて、キャンセルがループを停止する唯一の方法であることを示し、「while(!processExited)」がループを示すことができる場合、より読みやすくなります。外部プロセスがなくなるまで実行する必要があります。メンテナンスのしやすさや読みやすさの点で、間違いなく「リソースを無駄にする」ことは間違いなく正しいことです。「while(true)」はそれほど悪いことではありませんが、私の経験では、通常、より良い方法があります。
bobbymcr

1
+1。ほとんどの場合、真の無限ループは実際に発生するものではなく、停止したい条件があります(たとえば、プリンターが起動しているとき)。
ライライアン

1
…その場合はを使用する必要がありますbreak
Ry-


1

あなたがコードゴルフをしているなら、私はお勧めしfor(;;)ます。それを超えwhile(true)て、同じ意味を持ち、より直感的に見えます。いずれにせよ、ほとんどのコーダーは両方のバリエーションを理解している可能性が高いので、それは本当に問題ではありません。最も快適なものを使用してください。


2
ゴルフをしているなら、C#はとにかく間違った言語です。
SingleNegationElimination 2009

1

私が言う唯一の理由 for(;;)は、CodeDomの制限によるものです(ループはCodeDomを使用して宣言できず、forループは反復ループとしてより一般的な形式と見なされます)。

これは、forループ実装が通常のコードとCodeDom生成コードの両方に使用できるという事実以外に、これを選択するかなり緩い理由です。つまり、より標準的なものにすることができます。

注として、コードスニペットを使用してwhileループを作成できますが、ループ全体がスニペットである必要があります...


1

どちらも同じ機能を備えていますが、一般的にはが好まれwhile(true)ます。読みやすく理解しやすい...


0

常にtrueを返す式はすべて、whileループで問題ありません。

例:

1==1 //Just an example for the text stated before 
true

trueが同様に機能するのに、なぜ1 = 1のような比較を強制する必要があるのですか?計算式を使用するのは、NUMBER_OF_ARMS = 598-3596のような定数を定義するのと同じくらい愚かです。
JohnFx 2009

コードの前に記載された回答の例:)
ジョージ

0

コードの読みやすさの点で while(true)、どんな言語でも私はもっと理にかなっています。コンピューターがそれをどのように認識するかという点では、非常に効率的なコンパイラーとインタープリターの今日の社会では、実際に違いはないはずです。

パフォーマンスに違いがある場合、MSILへの変換は最適化されます。あなたが本当にしたいなら、あなたはそれをチェックすることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.