繰り返し構文について
RPG など、ゲームの処理というのは、プログラムの同じ部分を何度も何度も繰り返してリアルタイムに処理が行われています。ゲームの主な処理は、画面描画、入力に対する処理、キャラクターの動作などですが、これらの一連の処理が一定時間間隔で繰り返されることによって動きのある「ゲーム」が作られているのです。このように、プログラムにおいてある処理を繰り返しというのはとても重要なことのです。C 言語では繰り返し (ループ) 構文としていくつかの機能が提供されています。ここでは、それらのステートメントを紹介します。
for ステートメント
「カウンタ」とよばれる、繰り返し回数を数えるための変数を用いて、カウンタの値が一定の条件を満たすまで繰り返しを行うのが for ステートメントと呼ばれる構文です。使い方は、
for(初期化式; 条件式; ループ式) 繰り返す処理;
のように書きます。if ステートメントと同様、繰り返す処理はひとつの文でも、ブロックでもかまいません。for ステートメントの繰り返し動作は次のような手続きをもって行われます。
(1) 初期化式を実行する。
(2) 条件式を評価し、値が偽ならループを抜ける。
(3) 繰り返し対象の処理を 1 回実行する。
(4) ループ式を実行し、(2) へ戻る。
switch ステートメントから抜けるのに break ステートメントを使いましたが、for ステートメントを抜けるためにも break ステートメントを使います。つまり、条件式が偽になるか、break ステートメントが実行されるまでループは続きます。switch の中に for があったり、あるいはその逆のときに break ステートメントが実行された場合、break は一番内側のステートメントに対して働きます。この後説明する他のループ構文を抜けるためにも break ステートメントを使うのですが、これらが入れ子 (ネスト) になっている場合も同様で、一番内側のステートメントからしか break することはできません。使用例を見てみましょう。
for ステートメントの使用例
void main(){ int i, s = 0; for(i = 1; i<=10; i++){ s += i; if(!YesNoDialog("現在の i の値は "+i+" です。\nまだ続けますか?")) break; } SysDialog("合計値は "+s+" です。"); }
解説
for ステートメントの動作は上で説明した通りですので、順を追って考えていただければどのようなプログラムになっているかお分かりいただけると思います。なお、i++ の ++ というのは 1 加える演算子です (インクリメントといいます)。もうひとつ新しい書き方があります。s += i; という 1 文です。この += というのは足し算と代入を同時に行うための演算子で、この場合 s = s+i; と書いたのと同じことになります。他にも -=, *=, /=, … など、いろいろな代入演算子がありますが += だけわかれば他もわかりますね。それで、このプログラムは 1 から 10 までの数値を s という変数に足していき、最後に合計値を表示するというものです。また、ループごとに続けるかどうか聞き、「いいえ」が選択されたらそこで break ステートメントによりループを抜けています。
while ステートメント
for ステートメントを条件式だけにしたものが while ステートメントです。使い方は、
while(条件式) 繰り返す処理;
と書きます。動作の手続きは、
(1) 条件式を評価し、値が偽ならループを抜ける。
(2) 繰り返し対象の処理を 1 回実行し、(1) へ戻る。
となります。while ステートメントは無限ループによく使います。無限ループとは、条件式を使わずに、break ステートメントを実行するまで繰り返し続ける制御方法です。サンプルを見てみましょう。
while ステートメントの使用例
void main(){ int i = 1, s = 0; while(1){ s += i; if(!YesNoDialog("現在の i の値は "+i+" です。\nまだ続けますか?")) break; i++; } SysDialog("合計値は "+s+" です。"); }
解説
条件式の評価値は常に 1 ですので、条件式が偽になってループが終了することはありません。従って、「いいえ」を押すまで延々と繰り返しが行われます。また、for ステートメントと違い初期化式とループ式がありませんので、カウンタの初期化とインクリメントはそれぞれループ前とループ中で行わなければなりません。
do … while ステートメント
while ステートメントの、条件式の評価と繰り返し対象処理の実行を逆の順序で行うものが do … while ステートメントです。使い方は、
do 繰り返す処理; while(条件式);
と書きます。動作の手続きは、
(1) 繰り返し対象の処理を 1 回実行する。
(2) 条件式を評価し、値が偽ならループを抜ける。真なら (1) へ戻る。
となります。while(条件式) の後にもセミコロンがいるので注意してください。do … while ステートメントは他の 2 つと比べあまり使われません。よってサンプルは割愛します。
continue ステートメント
break ステートメントがループ構文 (及び switch) を抜けるために使われるのに対し、ループ構文の途中からループの最初に戻って次のループに進めるために使われるのが continue ステートメントです。これは上で説明した 3 種類のループ構文のどれでも使えますが、break ステートメントと違い switch ステートメントでは使えません。continue ステートメントが実行されると条件式が評価され、偽ならループを抜けます。真の場合は再び繰り返し対象処理が実行されます。for ステートメントの場合は、条件式の評価の前にループ式が実行されます。次に continue ステートメントを使用した例を示します。
continue ステートメントの使用例
void main(){ int i, s = 0; for(i = 1; i<=30; i++){ if(i%3) continue; s += i; } SysDialog("合計値は "+s+" です。"); }
解説
今度のスクリプトは、1 から 30 までの数のうち 3 の倍数であるものを合計するプログラムです。i が 3 の倍数でない場合は continue ステートメントを実行しています。i%3 というのは、i を 3 で割った余りを求めるという意味の演算子です。この % 演算子は整数型にしか使用できません。