【第10章】平均を求めるプログラム(2)選択処理


[回数が決まっていない繰り返し処理]

 不定回の繰り返し処理のやり方はおわかりいただけたでしょうか。回数が決まってないとはいえ、データの件数が無限ということはそうそうあることではありません。テストの平均点を求めるプログラムなら受験者の点数すべて入力し終わったらループは終了で、平均の計算に移ります。では、何人受験したかわからない学力テストの平均点を求めるプログラムではどうしたらよいでしょう。この場合、よく使われる方法は、「あり得ないデータ」が入ってきたところでループから抜けるというものです。この章ではさらに「条件によって処理内容を変える」という方法を学びます。コンピュータの最もコンピュータらしい部分で、これができるゆえに、筆者が小学生だった昭和40年頃は、コンピュータは「人工頭脳」と呼ばれたりしたものでした。今でも中国語では「電脳」といい、日本でも電脳少女など、ホビーの世界ではこの言い方が使われてますね。
 歳とると昔話が多くなってダメですね。話を元に戻します。たとえば

1)テストの点数は0点~100点の範囲である
2)点数に999が入力されたらデータ入力のループを抜ける
3)児童の出席番号(または受験番号)は1、2、3、・・・、Nとなっていて欠番はないものとする。

という前提で、不定回数の繰り返し処理によるテストの平均を求めるアルゴリズムを考えてみます。基本的な流れは次のようになります。


図10_1.受験者人数が一定でない学力テストの平均点を求める図10_1.受験者人数が一定でない学力テストの平均点を求める
図10_1.受験者人数が一定でない学力テストの平均点を求める

 上の図で、入力された点数が(たとえば)75のときと999のときでは処理の流れがどう変わるかを辿ってみてください。このアルゴリズムをTiny BASICでコーディング(プログラミング言語を使って実際にプログラムを作成すること)すると次のようになります。

         1: PRINT "***テストの平均点***"
         2: GOKEI=0
         3: NINZU=0
         4: BANGO=0
         5: TENSU=-1
         6: WHILE TENSU<>999
         7:   BANGO=BANGO+1
         8:   PRINT BANGO;"番";
         9:   INPUT "点数(999=END)",TENSU
       10:   IF TENSU<>999 THEN
       11:     GOKEI=GOKEI+TENSU
       12:     NINZU=NINZU+1
       13:   END IF
       14: WEND
       15: HEIKIN=GOKEI/NINZU
       16: PRINT "平均点は";HEIKIN
       17: END

      図10_3.受験者人数が一定でない学力テストの平均点を求めるプログラム

 1~3行目はもう説明不要ですね。
 4行目の変数BANGOは出席番号です。え?これ、NINZUを使えばいいんじゃない?と思われる方もいると思いますが、それはあまり感心しません。今ここでは番号の欠番はないものとしていますが、たとえば学校の場合、転校などによっていなくなった児童がいたりします。筆者の知る限りではこういうときその児童の出席番号は欠番となります(学年が変わってクラス替えがない限り1つずつ出席番号が前へずれるということはありません)。塾・予備校などの学力テストなら受験申し込みはしたものの受験はしなかったという児童・生徒がいるかもしれません。そういうとき、データ件数の値と出席番号(受験番号)の値が一致しなくなることは容易に想像がつきます。そのようなことにも対処できるようなプログラムにするにはデータ件数と出席番号は別々の変数にした方が後でプログラムの修正が楽になります。
 実際プロのプログラマが作ったプログラムを拝見すると後から機能の追加の要求がきたり、処理内容の一部に変更があってプログラムを修正(メンテナンス)する必要が出てきたときのことを想定して書かれていることがうかがえます。
 5行目はループに入るために、その条件となる変数TENSUに「得点の範囲外でループ終了条件とも違う値」を代入しています。WHILEの後ろの条件はループ実行条件であることを思い出してください。
 7~9行目、これで点数入力のループに入ったのですから出席番号を +1 して、点数入力です。
 10行目がこの章の主役、IF文です。ここでは「変数TENSUの値が999でないときはTHEN以下の処理をせよ」ということになります。どこまでかを示すのが13行目にあるEND IFです(詳細は次節で)。
 繰り返し処理はここまでなので14行目にはWENDがあり、6行目のループ実行判定に戻ります。もし今、入力した内容がループ終了条件の999だったら、11~12行目の処理は行なわずに6行目に戻ってくることになります。ここでTENSUの値は999ですから、ループ実行条件は成立せず(ループ終了条件が成立し)、15行目以下に飛びます。平均を計算し、表示してプログラムは終わります。


[IF ~ END制御文]

 このプログラム中に IF~END IFというのが出てきます。勘の良い方なら「ん?この構文は?FOR ~ NEXTやWHILE ~ WENDのように条件によってプログラムの実行順序を変える制御文かな?」と思ったことでしょう。その通りです。ただ、IF ~ END IFは繰り返し処理というより、条件によって処理内容が変わる選択処理に向いている制御文です。プログラミング言語によっては判断・分岐命令と呼ばれることもあります。
1)IF ~ END IF制御文の使い方の基本はこうなります。
  IF 条件式 THEN
    条件式が成立したときに実行される命令
  ELSE
    条件式が成立しなかったときに実行される命令
  END IF
ここで、条件が成立しなかった時に行なう処理が何もなければ、ELSE以下、END IFの手前までは省略できます(上のサンプルプログラムがそうです)。
2)さらに条件を細かく分けたいときには、このような使い方もできます。

  IF 条件式1 THEN
    条件式1が成立したときに実行される命令
  ELSEIF 条件式2 THEN
    条件式1が成立しないが、条件式2は成立したときに実行される命令
  ELSE
    条件式1も条件式2も成立しなかったときに実行される命令
  END IF

 これは少々わかりにくいと思いますので、実例でみてみましょう。図10-3のプログラムでは入力された値が1か2か、それ以外かによって、処理の内容が変わっています。


    PRINT "サービスデーのご案内"
    INPUT "お客様の性別は 1.男性 2.女性 3.無回答 ",SEI
    IF SEI=1 THEN
      PRINT "毎週火曜日は男性のお客様は¥1000で食べ放題"
    ELSEIF SEI=2 THEN
         PRINT "毎週木曜日は女性のお客様は¥1000で食べ放題"
    ELSE
    PRINT "毎週水曜日は¥1000で食べ放題"
    END IF
    PRINT
    PRINT "焼肉 〇〇"
    END


     図10_3.条件によって処理内容が選択されるプログラム

 入力内容が1か2か3かで処理の流れがどのようになるか(この例では画面に表示される内容)、考えてみてください。実行結果は図10-4のようになります。


図10-4.条件によって処理内容が選択される
図10-4.条件によって処理内容が選択される

 こんな焼肉屋さんがあったら、火・水曜日はいつもここで夕食ですなぁ(^ ^;
3)IF~END制御文も、FOR~NEXT制御文、WHILE~WEND制御文同様、ネスティングができます。

     1:SCORE=0
     2:PRINT "歴史クイズ"
     3:INPUT "日本最初の元号は 1.大和 2.大化 3.文化 ",ANS
     4:IF ANS=2 THEN
     5:    SCORE=SCORE+10
     6:    INPUT "徳川第八代将軍は 1.吉宗 2.家光 3.綱吉 ",ANS
     7:    IF ANS=1 THEN
     8:        SCORE=SCORE+10
     9:        INPUT "フランス革命の始まりとされているのは 1.ナポレオン台頭 2.ポーランド分割 3.バスティーユ監獄衝撃",ANS
    10:       IF ANS=3 THEN
    11:          SCORE=SCORE+10
    12:       ELSE
    13:          PRINT "正解は3.バスティーユ監獄襲撃です"
    14:       END IF
    15:   ELSE
    16:       PRINT "正解は1.吉宗です"
    17:   END IF
    18:ELSE
    19:    PRINT "正解は2.大化です"
    20:END IF
    21:PRINT "SCORE=";SCORE
    22:END

     図10-5.正解したら次へ進めるクイズのプログラム

 図10-5は1つでも正解できないと脱落するという(鬼畜な?)クイズゲームです。正解しないと次の問題に進めないというのはIF~ENDIFのネスティングで実現してます。1問目が正解なら5行目以下が実行され、不正解なら19行目へ飛んでプログラム終了です。しかし6~7行目に2問めと解答の判定があります。2問めも正解なら8行目以下が実行され、不正解なら16行目へ飛びます。ここで1問目は正解しているので18~20行目は無視して21行目へ飛び、プログラム終了です。同様に9~10行目に3問めと解答の判定があります。正解なら11行目を、不正解なら13行目を実行してプログラム終了です。

【Tiny BASICの文法(4)】マルチステートメント
 Tiny Basicでは1行に1ステートメントを書くのが普通ですが : (半角のコロン)を使って1行に2つ以上のステートメントを書くことができます(マルチステートメント)。たとえば
       T=0
       INPUT "Nの値は";N
       FOR I=1 TO N
       T=T+I
       NEXT I
       PRINT "1~";N;"の自然数の合計は";T
       END

のプログラムは次のように書いてもTiny Basicの文法としては間違いではありません。

T=0:INPUT "Nの値は";N:FOR I=1 TO N:T=T+I:NEXT I:PRINT "1~";N;"の自然数の合計は";T:END

 ただ、これは読みにくいことこの上ないですね。マルチステートメントはこのようにむやみに使うとプログラムがわかりにくくなる原因になります。昔のBASICはIF制御文はブロック化ができなかったので、このマルチステートメントは絶対必要だったのですが、今のTiny Basicでは必要ないものとなりました。マルチステートメントは使わないようにしましょう。

【昔はよかったなぁ】

 今回は「昔はよかった」ではなく「昔はひどかったなぁ」というお話です。
 図10-3のプログラムを昔のBASICで書くと図10-5のようになります。

図10-5.条件により処理内容が変わるプログラムを昔のBASICで書くと
図10-5.条件により処理内容が変わるプログラムを昔のBASICで書くと

 昔のBASICは END IF がありませんでした。つまりIFブロックは使えませんでした。入力内容により処理内容を変えたいなら行番号30のようにELSEIF(昔のBASICではELSE IF)以下を1ステートメントにしなければなりませんでした。
 また条件が成立した(反対に成立しなかった)時の処理が複数あるとき、それをすべて1ステートメントで書かなくてはならなかったので、図10-3のプログラムの10~13行目の部分を昔のBASICで書くと、
   IF TENSU<>999 THEN GOKEI=GOKEI+TENSU : NINZU=NINZU+1
となります。後でプログラムを見なおした時、自分で作ったプログラムなのに何が何だかわからないということもよくありました。今のTiny BasicはIF制御文もEND IFを使ってFOR制御文、WHILE制御文のようにブロック化し、わかりやすいプログラムが書けるようになりました。

【この章のまとめ】

条件によって処理内容が変わる処理を選択処理という。

Tiny BASICでは選択処理に向いている制御文はIF ~ END IF制御文である。基本的な書き方は

  IF 条件式 THEN
    条件式が成立したときの処理内容
  END IF

である。さらに条件を細かく分けたいときは
  IF 条件式1 THEN
    条件式1が成立したときの処理内容
  ELSEIF 条件式2 THEN
    条件式1は成立しないが、条件式2が成立したときの処理内容
  END IF

【演習6】ユーザー認証のプログラムを作ってみましょう。登録ユーザーは2人で、登録した名前で認証するものとします(ここでは変数で入れておくことにしておきます)。ユーザー名を入力し、登録ユーザー名のどちらかと一致すれば「〇〇(登録ユーザー名)さん、こんにちは」どちらとも一致しなければ「認証できませんでした」と表示するようにすること。このプログラムはいろいろな方法があるのですが、習熟のため、IF制御文を使うようにしましょう。

【ここまでのまとめ】

 ここまでで、プログラムの基本的な流れ「順次処理」「繰り返し処理」「選択処理」についてひととおりやってきました。コンピュータのプログラムはゲームのプログラムから銀行のシステム、人命を預かる新幹線の列車集中制御(CTC)のプログラムまで基本はこの3つの流れの組み合わせでできています。ここまでの内容がわかったら、ご自分のアイデアでプログラムを作ってみてください。そういう経験をたくさん積んでゆけば、プログラミング的思考とは何かがおのずとわかってくることでしょう。

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

名前

URL

メッセージ

- CafeLog -