12.繰り返し(5/30)




前章の「比較」と同じくらいに重要な命令に「繰り返し命(ループ命令とも言う)令」というものがあります。
この命令は呼び名のごとく、プログラムの特定範囲を「指定した回数」又は「指定した条件が成り立つ間」繰り替えして動作をさせる機能です。
この命令をどのようなシチュエーションで使うのかといえば、例えば
「グループ化されたある情報を順番に検索し、条件に合う情報を見つけだす」という使い方があります。


また、「ある条件になるまで処理を繰り返す」というのも良く使う利用法です。
この繰り返し命令には「FOR〜NEXT」「WHILE〜ENDWHILE」「LOOP〜ENDLOOP」という3種類が用意されていますが、今回は前2つの命令を説明します。

まずは「FOR〜NEXT」が、この命令は指定の回数だけ繰り返す命令です。もう少し具体的に言うと、指定した変数をカウンタとして使い、指定した初期値からループを1周する毎にカウントアップ(又はカウントダウン)し指定した数値になるまで処理をループします。
「FOR(発音=フォア、日本語=〜の間)」「TO(発音=トゥ、日本語=「FOR〜TO〜」で「〜から〜の間」))」「STEP(発音=ステップ、日本語=段階」)」「NEXT(発音=ネクスト、日本語=次へ)」という4つの命令で構成されます。
例えば、「1〜10までの整数の合計を表示する」プログラムを作る場合
CH=G@SETUP(640,480,8,1)
G@FONT(0,0,0,3,"MSゴシック")
B = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
G@PRINT(CH,0,0,STR( B ))
LOOP
G@FLIP()
ENDLOOP

というプログラムが単純に考えられます。まあ、1〜10という少ない数の計算ならばこれでも良いのでしょうが、例えば1〜10000などという数になったらお手上げです。ここでFOR文の登場となります。

CH=G@SETUP(640,480,8,1)
G@FONT(0,0,0,3,"MSゴシック")
FOR A = 1 TO 10
  B = B + A
NEXT
G@PRINT(CH,0,0,STR( B ))
LOOP
G@FLIP()
ENDLOOP

このプログラムも1〜10の合計を求めています。この処理の流れを順を追って説明します。
処理がFOR文まで来ると、FOR文とTO文の間で記述した「A=1」という代入文にしたがって変数Aに1を代入します。この場合、変数Aはカウンタの役目をし、1が初期値となります。


変数Aの初期化後FOR文の次の命令に処理が移ります。今回は「B=B+A」という様に変数Bに変数Aの内容を足して行きます。最初、変数Aには1が入っているので加算後は変数Bに1が入っています。

NEXT文までプログラム処理が進んだら、カウンタである変数Aに1を加えTO文の次に指定した10と比較し、( 変数A ≦ 10 )が成り立つならばFOR文の次の命令に処理が戻ります。
今は変数Aに1を入れたばかりなので、( 変数A ≦ 10 )が成り立ちます。


2周目となる「B=B+A」では、変数Aには2が入っているので「B=1+2」で変数Bは3となります。

またNEXT文までプログラム処理が進んだら比較をするという作業を繰り返します。
そして10周目の時に変数Aに10が入っているので、NEXT文でのカウンタ更新で変数Aは11となり、( 変数A ≦ 10 )が成り立たなくなります。成り立たなくなったらNEXT文の次の命令に処理が戻ります。

これが「FOR〜NEXT」の一連の処理手順です。補足ですが「FOR〜NEXT」の繰り返しから抜けた時点では変数Aには11が入っている事を覚えておいてください。
最後になりますが、これまでの説明では「FOR〜NEXT」を1周する毎にカウンタに1を加えてますが、カウンタに加える数値は変更する事が出来ます。それにはSTEP文を使います。
例えばカウンタを2ずつ増やしたい場合は、TO文の後に「STEP 2」という記述を追加してください。
CH=G@SETUP(640,480,8,1)
G@FONT(0,0,0,3,"MSゴシック")
FOR A = 1 TO 10 STEP 2
  B = B + A
NEXT
G@PRINT(CH,0,0,STR( B ))
LOOP
G@FLIP()
ENDLOOP

結果は、「1+3+5+7+9」の合計の25になります。
また、カウンタを1ずつ減らしたい場合には、TO文の後に「STEP −1」という記述を追加してください。
この場合、NEXT文での比較は( 変数A 10 )となります。次のプログラムは10〜1の加算を行います。

CH=G@SETUP(640,480,8,1)
G@FONT(0,0,0,3,"MSゴシック")
FOR A = 10 TO 1 STEP -1
  B = B + A
NEXT
G@PRINT(CH,0,0,STR( B ))
LOOP
G@FLIP()
ENDLOOP


次に「WHILE〜ENDWHILE」ですが、この命令は指定の比較式が成り立つ間だけ繰り返す命令です。もう少し具体的に言うと、「WHILE〜ENDWHILE」の繰り返しの最初でWHILE文の次に書いた比較式を実行し、比較が成り立てば繰り返しの中を実行、比較が成り立たなければ繰り返しの中を実行せずにENDWHILEの次に処理を移します。
例えば、「1,2,3・・・と順番に数値を加算して行き合計が10000を超えるた時に加算した値を表示する」プログラムを作る場合、

CH=G@SETUP(640,480,8,1)
G@FONT(0,0,0,3,"MSゴシック")
WHILE B < 10000
  A = A + 1
  B = B + A
ENDWHILE
G@PRINT(CH,0,0,STR( A ))
LOOP
G@FLIP()
ENDLOOP

となります。WHILE文に最初に処理が来た時には変数A、B共に0が入っているので、WHILE文に書いた「B<10000」は成り立ち「WHILE〜ENDWHILE」の中に処理が移ります。


まず「A=A+1」で変数Aに1を加えます。これは「1,2,3・・・と順番に数値を加算・・・」とする為に変数Aを加算して行く値とし、毎回1ずつ大きくして行く為の処理です。最初変数Aには0が入っているので、1周目の結果は変数Aに1が入る事になります。
次の「B=B+A」ですが、変数Bを合計した結果を入れる為に使い、1ずつ増えて行く(1,2,3・・・)値を加算して行きます。最初変数Bには0が入っているので、1周目の結果は「B=0+1」となり1が入る事になります。
ENDWHILE文までプログラム処理が進んだら、WHILE文に処理が戻り、「B<10000」の比較を実行します。1周目が終わった時点では比較が成り立ち、再び「WHILE〜ENDWHILE」の中に処理が移ります。

2周目は変数Aは2となり、変数Bは「B=1+2」で3が入ります。変数Bが10000を超えるのは、まだまだ先なので説明を10000を超える所まで飛ばします。10000を超えるのは141周目になります。
141周目は変数Aは141となり、変数Bは140周までの合計である9870に変数Aを加算し10011となります。
ENDWHILE文までプログラム処理が進んだら、140周まで繰り返したと同じようにWHILE文に処理が戻り、「B<10000」の比較を実行します。今回は比較が成り立たない為、ENDWHILE文の次に処理が移ります。
これが、一連の処理手順です。


ここまでで、繰り返し命令の説明を終えますが、なんとか理解できたでしょうか?
あと、ちょっとした事なのですが、繰り返し文でループするプログラムの部分をプログラムする時に、少し右にずらしてあげると、プログラムが見やすくなります。
FOR A = 1 TO 10
B = B + A
C = C + A
D = D + A
E = E + A
NEXT

と、書くよりも

FOR A = 1 TO 10
  B = B + A
  C = C + A
  D = D + A
  E = E + A
NEXT

と、書いた方が繰り返す範囲が分かりやすくありませんか?