この記事は、絵でわかる プログラムとは何か(7)~フロー~ の最初に読んでいただくべき記事です。
この記事のポイント
- 高級言語では、処理の流れ(フロー)を制御するために、言語仕様で決められたキーワードを、決められた位置で使うステートメント=制御構文(control flow statement)がよく使われる。
- フローの詳細解析を、制御構造(control structure)と言う。
- 制御構文(制御構造)は、主に分岐とループに分かれる。
- スイッチの「切り替え」を、プログラムで表現したものを分岐と言う。
- 分岐には、if 文 がよく使われる。
- 分岐構文は、if 文 の他に、switch 文 や try 文 などもある。
- 分岐の片方を、分岐前の処理に戻す、特殊な分岐をループと言う。
- ループ構文には、for 文、while 文、until文 などがある。
制御構文(control flow statement)とは
ラベルに翻訳される関数と制御構文
高級言語は、言語処理系によって、マシンコードやアセンブリ言語といった低級言語に翻訳されます。
低級言語では、モジュール化のためにラベルへの参照がよく使われます。
しかし高級言語では、単純なラベルは、処理の流れ=フロー(flow)をわかりにくくするため、あまり使われません。
ラベルを使わない、最もシンプルなフローであれば、以下のようなイメージです。
ラベルの代わりに高級言語でよく使われるのが、関数と制御構文です。
関数は、モジュールの一種として、言語処理系で翻訳時に、ラベルに変換され、呼出規約(calling convention)に従い、関数名の call からリンクされます。
一方、制御構文は、言語仕様で決められたキーワードを、決められた位置で使ったステートメント(構文)です。
このステートメントには、判定と、その判定に基づいた処理(制御)を記述します。
このステートメントは、言語処理系で翻訳時に、ラベルと演算命令とジャンプ命令に変換されます。
そうしてプログラム実行時に、レジスタに記録されているデータが演算され、その演算結果に基づいたラベル位置へ、処理の流れ(flow)をジャンプさせます。
このような処理の流れの構造を、制御構造(control structure)と言います。
制御構文(制御構造)は、主に分岐とループに分かれます。
分岐(branch)
コンピューターは元々、リレースイッチの組み合わせでした。
スイッチ(switch)というのは、「切り替え」です。さらに、リレースイッチは、電気の ON / OFF によって、さらに次々と、電気の ON / OFF 切り替えリレーができるスイッチです。だから、電気回路(電子回路)をうまく作れば、二進数の入力に対して、意図したとおりの変換処理を行い、その結果を二進数で出力できる、というのがコンピューターの原理でした。
これがよくわからないという方は、絵でわかる プログラムとは何か(1)~コンピューターの原理から~ をご覧ください。
この「切り替え」をプログラムで表現したのが分岐です。場合によっては、ランダムな切り替えも考えられますが、多くの場合、入力値に従った条件分岐(振り分け)が採用されます。
複雑な条件であっても、根底にあるのは、やはり右か左かに分かれるだけの二分岐です。複雑に見える条件も、true(真) / false(偽) の二者択一の組み合わせと考え、分解していけば、最終的に二分岐の組み合わせで表現できます。
言葉がややこしいですが、二分岐の組み合わせで表現される複雑な分岐は、二分木と言います。
if 文
多くのプログラミング言語では、二分岐を表現する構文として、if 文が用意されています。
if 条件式 then 処理 else 別処理
言語によって異なりますが、薄字の部分は通常、省略が可能です。
文末の「 else 別処理 」は、条件式が false(偽) の場合(条件に適合しない場合)の処理です。
「 else 別処理 」を省略した場合(書かなかった場合)、条件式が false になると、その if 文では何も行われず、次の文に進みます。
その他の分岐構文
その他の分岐構文としては、複数条件分岐(選択)をまとめて指定できる switch 文や、エラーの発生時にだけ分岐させる try 文などがあります。
switch 文では、途中の分岐で true(真) になっても、最後の分岐まで継続して、全ての判定がされる場合があります。
その場合、各分岐の true に break を入れておくことで、その時点で switch 文 を退出できるようになります。
ループ(loop)
ループは特殊な分岐
ループは、分岐の片方を、分岐前の処理に戻す、特殊な分岐です。
英語の loop は、「輪っか」、「循環」という意味です。
ループも分岐の一種なので、制御構造で重要なのは、結局「分岐だけ」とも言えます。しかし、フロー図を見比べると、通常の分岐とループでは、だいぶ違っていて別物に見えるため、分岐とループに分けて二大制御構造として扱うことが多くなっているのです。
他に、何も制御しない継続や、それ以上進めない停止などを、制御構造に含める場合もあります。
ループでは、分岐の前処理でカウンタ(変数)を更新し、分岐の条件式でそのカウンタを判定させて、条件式が true / false どちらかの場合だけ、分岐の前処理に戻って… と繰り返し処理をさせるのが、一般的です。
ループでの条件判定に使う変数は、ループ回数をカウントする変数にすることが多いので、カウンタと言います。
カウンタ変数、ループ変数、ループカウンタ変数、ループカウンタ などとも言います。(呼び名までループしちゃってますね)
具体的には、以下のようにカウンタの更新とカウンタの判定をします。
カウンタの更新
カウンタの初期値を0または1にして、分岐するたびに(分岐後に戻った前処理で)、+1ずつ増やします。これで、ループ回数をカウントできます。
カウンタの判定
ループをちょうど100回繰り返したければ、条件式で、カウンタが100に達したかどうかを判定させます。達していなければ、分岐の前処理に戻し、達していればループ終了とします。
やや正確ではない言い方ですが、カウンタは必ずしも「回数」をカウントする必要はありません。
ループを続けるか、終了するかの判定に使う変数として、自由に利用されます。
無限ループ(永久ループ)
カウンタを更新しなかったり、ずっと終了判定にならない条件式にしたりすれば、無限ループ(永久ループ)になります。
無限ループはバグである場合もありますが、意図的にプログラミングすることもあります。
もちろん、無限/永久と言っても、プログラムを停止/終了すれば、ループも停止/終了します。
ループ構文
ループは、for 文や while 文、until 文などで記述します。
for 文
for 範囲式 処理
for 文は、その文中で範囲式と処理を指定し、その範囲内の各要素ごとに、処理を繰り返す制御構文になります。
範囲指定することで、繰り返し回数がその範囲の要素数に限定されます。
例えば、1, 2, …, 100 という範囲を指定すれば、for 文の処理は100回繰り返した後に自動的に終了します。
while 文
while 条件式 処理
while 文は、その文中で条件式と処理を指定し、処理のたびにその条件式を再判定し、判定結果が true であれば処理を行うことを繰り返します。
判定結果が false であれば、while 文を終了します。
until 文
until 条件式 処理
until 文は、その文中で条件式と処理を指定し、処理のたびにその条件式を再判定し、判定結果が false であれば処理を行うことを繰り返します。判定結果が true であれば、until 文を終了します。(判定結果と処理との関係が、while 文と逆)
この記事のまとめ
高級言語では、処理の流れ(フロー)を制御するために、言語仕様で決められたキーワードを、決められた位置で使うステートメント=制御構文(control flow statement)がよく使われます。
フローの構造を、制御構造(control structure)と言います。
制御構文(制御構造)は、主に分岐とループに分かれます。
スイッチの「切り替え」を、プログラムで表現したものを分岐と言います。
分岐には、if 文 がよく使われます。
分岐構文は、if 文 の他に、switch 文 や try 文 などもあります。
分岐の片方を、分岐前の処理に戻す、特殊な分岐をループと言います。
ループ構文には、for 文、while 文、until文 などがあります。
次は、割り込み・イベント・例外 に進みましょう。
この記事は、絵でわかる プログラムとは何か(7)~フロー~ の一記事です。
コンピューターのしくみ全体を理解したい場合は、以下の2コースがお勧めです。
日本全国 オンラインレッスン にも対応しています。
知りたいことだけ単発で聞きたい場合は、 オンラインサポート をご利用ください。