ループ (プログラミング)
この記事では、コンピュータプログラムにおけるループ (英: loop) について説明する。ループとは、特定の条件下において特定の処理を繰り返すこと、あるいはそのように作られた制御構造のことを言う。日本語の名詞として「繰り返し」とも。特定の条件が成立している限り、特定の処理を繰り返し何度でも実行する。逆に言えば、条件が成立しなくなったときに、処理を中止する。
ループの、特別な形あるいは最も一般的な形として、無条件に繰り返す無限ループがある。詳細は無限ループの記事を参照。
ループは、繰り返しを継続するかどうかを判断するための条件式(反復条件)を持つ。反復条件がループ構造の始まりに置かれる場合、そのようなループ構造のことを前判定ループと呼ぶ。一方、反復条件がループ構造の後ろに置かれる場合、これを後判定ループと呼ぶ。しかし結局のところ以上のような分類は、プログラミング言語の発展の初期に、まず最初にどちらか片方だけが作られ、後から別のものが追加されたという歴史的由来に過ぎず、ループの「内側」のどこかに「ループの脱出」がある、という構造に一般化できるので前判定/後判定という分類は本質ではない(実際に、たとえばVisual Basicの「Do...Loop 文」は、どの場合にも対応するよう対称的に作られている)。単にその「内側のどこか」が、その前端か後端にある場合が多い、というだけである。
むしろ、ループの先頭で何らかのデータをファイルから読み込んで計算を開始し、その途中で、繰り返しのその回を打ち切り次の繰り返しに進む、あるいは繰り返しを終わる、といったこともよくあり(ダイクストラは、最後が途中で終わる場合を「n+1/2回の反復」と名づけた)、さらには入れ子になった内側のループの中から外側のループを終わる、というような処理にどう対応するか、が思案のしどころである。
関数型プログラミングのスタイルでは、再帰によってループを扱うことが多い。単純な再帰呼び出しはスタックオーバーフローを引き起こす可能性があるが、末尾再帰はコンパイラ最適化によってループに展開される。
処理待ちのためのループ
[編集]かつてのプログラミング環境では、処理待ちをするためにループを使用する場合があった。例えば、
ユーザーが何かキーを入力するまで待機する:
10 PRINT "Press any key to continue: "
20 IF INSTR$ = "" THEN GOTO 20
30 PRINT "Thank you!"
一定の時間間隔をおいて処理を行う:
10 PRINT "A"
20 FOR I = 0 TO 10000: NEXT
30 PRINT "B"
40 FOR I = 0 TO 10000: NEXT
50 PRINT "C"
などである。これらのコーディングテクニックは、スリープ機能やマルチタスク機能、イベント(メッセージ)やスレッド機能などが用意されていなかったために使用せざるを得なかったものであり、現代的なオペレーティングシステムにおけるプログラミング環境ではほとんど使用されることはない。特にスピンループを使用した待機は、実際の待機時間がプロセッサ(CPU)のハードウェア仕様(クロック周波数)に左右され、また負荷に応じてクロックが変動する動的オーバークロック機構(Intel Turbo Boostなど)を備えたプロセッサでは通用しない。さらに、スピンループは1つのプログラムが延々とプロセッサ時間(CPU時間)を使い続けることになり、電力効率が悪くなったり、優先順位の低い別のタスクの実行速度に悪影響を与えたりする[1]。コンパイラの最適化によって、無意味なループは除去されてしまうこともある[2]。
構文
[編集]以下は手続き型言語でループする制御構造を記述するための代表的な文である。実際のキーワード(あるいは予約語)や構文仕様は言語によって異なる。文ではなく式として実装されている言語もある[3]。
これらの専用構文を使わずとも、if文とgoto文を使ってループを記述することも可能であるが、可読性やメンテナンス性の観点からループ専用構文を使うことが望ましい。なお、高級言語のループ専用構文を使って書かれたプログラムを実際にコンパイルして機械語や中間表現に変換すると、内部的には分岐命令やジャンプ命令に置き換えられる。