リンクされた記事は、ドナルド・クヌースのN + 1/2ループについて間違いなく正しく理解しています。C / C ++ / Javaで表現:
for (;;) {
get next element;
if (at the end) break;
process the element;
}
これは、ファイルから行または文字を読み取り、EOFに到達したかどうかをテストしてから処理するのに役立ちます。私はパターンfor(;;)..if(..)break;
が現れるのを見るのに慣れており、それは私にとって慣用的です。(Knuthの記事を読む前に、Literate Programmingという本に転載されていましたが、これはかつて「wtf?」でした。)
Knuthはキーワードを提案しましたloop/while/repeat
:
loop:
S;
while C:
T;
repeat
どこS
とT
ゼロ個以上の一連の文のためのプレースホルダであり、C
ブール条件です。S
ステートメントがない場合はwhileループになり、T
ステートメントがない場合はdoループになります。
このコンストラクト自体は、ゼロ個以上のwhile C
句を許可することで一般化でき、無限ループを表現するのに最適であり、2つのチェックを必要とするまれな条件になります。
同じ記事で、Knuthは、(gotoを使用する代わりに)例外をスロー/キャッチするローカルバージョンになるシグナリングメカニズムを提案しました。
私のために?私は私が表現できるように、Javaは、末尾呼び出しの最適化をサポートしたい任意の必要に応じて一般的な制御構造を。
更新:多くのC / C ++ / Javaプログラマーが、次の条件で埋め込み割り当てを使用してこの問題を回避することを忘れていましたwhile
。
while ((c = getc(f)) != -1) {
T;
}
Knuthの構築物から用語を使用して、これが許容されるとき、S
およびC
単一の式にまとめることができます。上記の埋め込み割り当てを見るのが嫌いな人もいれば、上記のものを見るのが嫌いな人もbreak
いfor (;;)
ます。場合しかし、S
及びC
そのような場合のように、組み合わせることができないS
複数のステートメントを有し、for (;;)
繰り返しコードなし唯一の選択肢です。もう1つの方法は、単にS
コードを複製することです。
S;
while (C) {
T;
S;
}
Knuthのloop/while/repeat
代替案ははるかに優れているようです。