【第7章】繰り返し処理

[一定回数同じ処理を繰り返すプログラム]

 ここまでずっと順次処理ばかりやってきました。前にも言ったとおり、プログラムの最初から最後まで順番に命令を実行してゆく順次処理はコンピュータのプログラムの基本なのですが、これだけではコンピュータを使うメリットはあまり感じられません。電源が安定して供給され、故障や過熱による部品破損などがない限り疲れを知らないコンピュータらしい仕事といえば、同じ命令を何回も実行する繰り返し処理でしょう。
 図7-1のプログラムを実行してみてください。2、3行目のインデント(字下げ)はしなくても結果は変わりません。結果は図7-2.のようになります。

            FOR I=1 TO 5 
              PRINT "HELLO. Tiny BASIC"
              PRINT 3+5
            NEXT I
            END


             図7-1.同じことを繰り返すプログラム
 

図7-2.同じことをくり返した
図7-2.同じことをくり返した


 プログラム2行目にPRINT "HELLO. Tiny BASIC"とあり、3行目にPRINT 3+5とありますから、このプログラムは"HELLO. Tiny BASIC"というストリングと、3+5の計算結果を表示することはおわかりになると思いますが、実行結果を見るとこれが1セットで5セット(5回)表示されています。なぜこうなったのでしょうか。それは1行目の FOR I=1 TO 5 と4行目の NEXT が為せる業です。
 FORはこの場合、For You のForではなく、「~の間」と考えてください。 1行目は「変数 I の値が 1 から始まり 5 になるまでの間、以下を実行せよ」の意味になります。以下ってどこまで?ということになりますが、それを指示するのが4行目の NEXT です。「次」という意味ですが、NEXT ~で「次の~」ということになりますから、繰り返しはここまで、という指示と考えてください。このプログラムでは変数 I の値は繰り返しに突入する時に自動的に 1 とされ、NEXT I に来たところで、これまた自動的に +1 されます。このようにして 5 になって最後の回を実行して NEXT I に来たところで、 +1 されて 6 になります。これでFORに戻ると、すでに繰り返しの条件「 I が 5 になるまで」は満たしていますから、もう繰り返し部分には入らず、NEXT の次の行に移る、というわけです。
 この FOR ~ NEXT のように、プログラムの実行順序を変えたりするステートメントのことを制御文といいます(制御文はそれ自体、入力、処理、出力などは行なわず、プログラムの動作をコントロールするだけです)。筆者が知る限り、ほとんどのプログラミング言語で、この FOR ~ NEXT に相当する繰り返し制御文がありますので、これはぜひ使えるようになってください。

図7_3.FOR~NEXTによる繰り返し処理の流れ
図7-3.FOR~NEXTによる繰り返し処理の流れ



[FOR ~ NEXT制御文]
 FOR ~ NEXT制御文の書き方は次の通りです。

   FOR 変数=初期値 TO 終端値 STEP 増分

     繰り返し実行する命令
         |
         ↓
   NEXT 変数

1)FOR は必ず NEXT とペアでなくては使えません。
 FORとNEXTで囲まれた部分をFORブロックといいます。
 FOR文で使用する変数(上の例なら I )をループカウンタ(ループ変数)といいます。
2)両方の変数は同じで、かつ数値が入るもの(数値型変数)でなくてはなりません。NEXTの後ろの変数名は省略できますが、その場合、そこから前の方にさかのぼっていちばん近い FOR とペアだとみなされます。

3)FOR 変数=初期値 TO 終端値 STEP 増分は、「変数の値が初期値から始まって増分値ずつ変化し終端値に達するまでの間」の意味になります。増分は省略できます。省略した場合は +1とみなされます。したがって、図7-4のプログラムは図7_1.と同じ結果になります。

            FOR I=38 TO 42
               PRINT "HELLO. Tiny BASIC"
               PRINT 3+5
            NEXT I
            END

               図7-4.初期値、終端値

 初期値>終端値で増分を負の数にすることもできます。実行結果は図7_2のとおりです。

             FOR I=5 TO 1 STEP -1
             PRINT "発射";I;"秒前"
             NEXT I
             PRINT "発射!---→"
             END

図7_5.FOR~NEXTによる繰り返し処理の流れ
図7_5.増分値を負の数にした例(ロケット発射)

4)FORブロックはプログラム中にいくつあってもかまいません。次のプログラムでは、5~7行目10~12行目の2箇所にFORブロックがあります、実行結果は図7-4のとおりです。

      INPUT "お名前は";NAMAE$
      INPUT "1~10000の自然数を入力してください",N
      T=0

      FOR I=1 TO 5
        PRINT "Hello,";NAMAE$;"さん"
      NEXT I

      PRINT

      FOR I=1 TO N
        T=T+I
      NEXT I


      PRINT "1から";N;"までの自然数の和は";T

      END

図7_6.FORブロックが複数あるプログラム
図7_6.FORブロックが複数あるプログラムの実行結果

5)FORブロックの中にFORブロックを含むことができます。これをネスティング(入れ子)といいます。次のプログラムを実行すると結果は図7-5のようになります(掛け算九九です)。

      PRINT "掛け算九九表"
      PRINT " | 1 2 3 4 5 6 7 8 9"
      PRINT "--+------------------------------------"
      FOR I=1 TO 9
        PRINT I;"|";
        FOR J=1 TO 9
          A=I*J
          PRINT USING " ## ";A;
        NEXT J
        PRINT
      NEXT I
      END

図7_7.ネスティングのあるプログラム
図7_7.ネスティングのあるプログラムの実行結果

 ネスティングでは子ブロックは完全に親ブロックの中に包括されている必要があります。次の例だと左はOKですが、右はダメです。

   FOR I = 0 TO 10           FOR I=0 TO 20

     FOR J = 0 TO 10           FOR J = 0 TO 10

     NEXT J             NEXT I 

    NEXT I                 NEXT J

[ループカウンタ取り扱い上の注意]

 ループ変数はそのブロックの中で参照(ループ変数の中味を見たり、計算式の右辺に使用すること)することはできます。しかし、ループ変数自体に何かを代入すると思わぬ事態になることがあります。

 たとえば次のプログラムを実行するとどうなるでしょう。

      FOR I=10 TO 15
        PRINT "ピーターパンは";I;"歳になりました"
        I=10
      NEXT I
      END

      図7-8.ループカウンタの値をブロック内で変更すると

 FOR~NEXTループに入ったところで I の値は10です。次のPRINT命令は"ピーターパンは";I;"歳になりました"となっています。 の現在の値は10ですから、"ピーターパンは10歳になりました"と表示されます。3行目でループ変数である I に10を代入しているので、4行目のNEXT Iでは I の値は 11 になります。FORに戻ったところで I はまだ終端値になっていないので次はピーターパンは 11 歳になりました"と表示されます。次は 12 歳になるところですが、3行目の I=10 があるため、ここを繰り返し通る度に I は10に戻ってしまい、NEXT I まで来てもループ変数は再び 11 になります。その結果、このプログラムはピーターパンが 11 歳になったところで永遠に終わらない永久ループになります。「ピーターパンは永遠に歳をとらない男の子なんだからこれでいい」ではなくて、これはプログラムのミスでコンピュータが暴走しているのですから、プログラムを強制的に終了させなくてはなりません。「よし、バッテリーパックを外そう」、ダ、ダ、ダメですよぉ(冷汗)。稼働中のコンピュータの電源部に手を触れるなど危険きわまりない!

図7-9.永久ループしたプログラムの強制終了
図7-9.永久ループしたプログラムの強制終了

 実行中のプログラムを強制終了するには、実行画面上布施にある中断をクリックします(図7-6)。実行が停止し、実行画面にはOKの表示が出ます。
 このようにループ変数に何かを直接代入するとプログラムの暴走につながるバグ(bug=虫、プログラム中のミスのこと)を招きかねません。そして筆者の経験で言えば、この手のバグを探すのはかなり大変です(1坪ほどの地面からダンゴ虫を見つけるのと同じくらい)。ループ変数はその内容を使う(参照といいます)のはかまいませんがループ変数そのものの値を変えるのはやめておきしょう

[PRINT USING "~"]書式を指定して表示

 PRINT命令は続くオペランドの内容を表示するもので、手軽に使えて便利なのですが、数値もストリングもすべて左詰めで表示します。ストリングはそれでいいとしても数値は帳簿等に書く時も普通は右詰めで書きます。小数点以下を含む数値なら小数点の位置を合わせて書きます。PRINT命令でもこのように表示させるのが図7-7のプログラムに出てくるPRINT USING命令(書式指定)です。USINGの後ろの" "の部分には書式設定子が入ります。書式設定子にはいろいろなものがあるのですが、現時点では数値の書式設定だけ覚えておきましょう。
 数値の書式設定子には、#、.、,、\(すべて半角)があります。
   # は数字を表示する位置を指定します
   . は小数点の位置を指定します
   , はカンマの位置を指定します
\ を先頭につけると最上位桁の前に \ マークを付けます

 次のプログラムを実行すると結果は図7-10のようになります。

        A=1234500
        B=12345
        C=123.45
        D=12.345
        PRINT USING "##,###,###";A
        PRINT USING "##,###,###";B
        PRINT
        PRINT USING "###.##";C
        PRINT USING "###.##";D
        PRINT
        PRINT D
        END

図7-10.書式設定のサンプル
図7-10.書式設定のサンプル

[この章のまとめ]

 プログラムの全体または一部を何回も繰り返し実行することを繰り返し処理(またはループ)という。

 計算や代入、表示ではなく、プログラムの動きをコントロールする分を制御文という。

 Tiny BASICでは FOR ~ NEXT制御文を使うことによって繰り返し処理(ループ)が実現できる。使い方は

  FOR ループ変数=初期値 TO 終端値 STEP 増分

    繰り返し実行する命令

  NEXT ループ変数

ループ変数の内容を繰り返し処理の中で参照するのはよいが、ループ変数そのものの値を変えるようなことは避けた方がよい。

FORブロックは1つのプログラムの中にいくつあってもよい。

fORブロックの中にFORブロックを含めることができる(ネスティング)。

PRINT USINGは書式を設定して画面表示する命令である。

【演習4】FOR ~ NEXT制御文を使って、1 から15までの自然数のうち、奇数( 2 で割り切れない数)を表示するプログラムを作りなさい。また 3 から15までの自然数のうち 3 の倍数を表示するプログラムはどうなるでしょう。

コメント一覧
コメント投稿

名前

URL

メッセージ

- CafeLog -