ステイホームで海外旅行(2)
2020.05.03
ステイホームで海外旅行(1)
2020.05.02
【第10章】平均を求めるプログラム(2)選択処理
2020.03.30
不定回の繰り返し処理のやり方はおわかりいただけたでしょうか。この章ではさらに「条件によって処理内容を変える」という方法を学びます。コンピュータの最もコンピュータらしい部分で、これができるゆえに、筆者が小学生だった昭和40年頃は、コンピュータは「人工頭脳」と呼ばれたりしたものでした。今でも中国語では「電脳」といい、日本でも電脳少女など、ホビーの世界ではこの言い方が使われてますね。
話を本題に戻します。回数が決まってないとはいえ、データの件数が無限ということはそうそうあることではありません。テストの平均点を求めるプログラムなら受験者の点数すべて入力し終わったらループは終了で、平均の計算に移ります。では、何人受験したかわからない学力テストの平均点を求めるプログラムで「ここでデータ入力終わり」ということをどうやってプログラムに知らせたらよいでしょう。これにはいくつかの方法がありますが、よく使われる方法は、「あり得ないデータ」が入ってきたところでループから抜けるというものです。たとえば
1)テストの点数は0点~100点の範囲である
2)点数に999が入力されたらデータ入力のループを抜ける
3)児童の出席番号(または受験番号)は1、2、3、・・・、Nとなっていて欠番はないものとする。
という前提で、不定回数の繰り返し処理によるテストの平均を求めるアルゴリズムを考えてみます。基本的な流れは次のようになります。
図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
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制御文]
このプログラム中に IF~END IFというのが出てきます。勘の良い方なら「ん?この構文は?FOR ~ NEXTやWHILE ~ WENDのように条件によってプログラムの実行順序を変える制御文かな?」と思ったことでしょう。その通りです。ただ、IF ~ END IFは繰り返し処理というより、条件によって処理内容が変わる選択処理に向いている制御文です。プログラミング言語によっては判断・分岐命令と呼ばれることもあります。IF ~ END IF制御文の使い方の基本はこうなります。
IF 条件式 THEN
条件式が成立したときに実行される命令
ELSE
条件式が成立しなかったときに実行される命令
END IF
ここで、条件が成立しなかった時に行なう処理が何もなければ、ELSE以下、END IFの手前までは省略できます(上のサンプルプログラムがそうです)。
さらに条件を細かく分けたいときには、このような使い方もできます。
IF 条件式1 THEN
条件式1が成立したときに実行される命令
ELSEIF 条件式2 THEN
条件式1が成立しないが、条件式2は成立したときに実行される命令
ELSE
条件式1も条件式2も成立しなかったときに実行される命令
END IF
これは少々わかりにくいと思いますので、実例でみてみましょう。次のプログラムでは入力された値が1か2か、それ以外かによって、処理の内容が変わっています。
PRINT "サービスデーのご案内"
INPUT "お客様の性別は 1.男性 2.女性",SEI
IF SEI=1 THEN
PRINT "毎週火曜日は男性のお客様は¥1000で食べ放題"
ELSEIF SEI=2 THEN
PRINT "毎週木曜日は女性のお客様は¥1000で食べ放題"
ELSE
PRINT "毎週水曜日は¥1000で食べ放題"
END IF
PRINT
PRINT "焼肉 〇〇"
END
入力内容が1か2か、それ以外かで処理の流れがどのようになるか(この例では画面に表示される内容)、考えてみてください。実行結果は次のようになります。
条件によって処理内容が選択される
こんな焼肉屋さんがあったら、火・水曜日はいつもここで夕食ですなぁ(^ ^;
[この章のまとめ]
条件によって処理内容が変わる処理を選択処理という。
Tiny BASICでは選択処理に向いている制御文はIF ~ END IF制御文である。基本的な書き方は
IF 条件式 THEN
条件式が成立したときの処理内容
END IF
である。さらに条件を細かく分けたいときは
IF 条件式1 THEN
条件式1が成立したときの処理内容
ELSEIF 条件式2 THEN
条件式1は成立しないが、条件式2が成立したときの処理内容
END IF
【演習6】ユーザー認証のプログラムを作ってみましょう。登録ユーザーは2人で、登録した名前で認証するものとします(ここでは変数で入れておくことにしておきます)。ユーザー名を入力し、登録ユーザー名のどちらかと一致すれば「〇〇(登録ユーザー名)さん、こんにちは」どちらとも一致しなければ「認証できませんでした」と表示するようにすること。このプログラムはいろいろな方法があるのですが、習熟のため、IF制御文を使うようにしましょう。
話を本題に戻します。回数が決まってないとはいえ、データの件数が無限ということはそうそうあることではありません。テストの平均点を求めるプログラムなら受験者の点数すべて入力し終わったらループは終了で、平均の計算に移ります。では、何人受験したかわからない学力テストの平均点を求めるプログラムで「ここでデータ入力終わり」ということをどうやってプログラムに知らせたらよいでしょう。これにはいくつかの方法がありますが、よく使われる方法は、「あり得ないデータ」が入ってきたところでループから抜けるというものです。たとえば
1)テストの点数は0点~100点の範囲である
2)点数に999が入力されたらデータ入力のループを抜ける
3)児童の出席番号(または受験番号)は1、2、3、・・・、Nとなっていて欠番はないものとする。
という前提で、不定回数の繰り返し処理によるテストの平均を求めるアルゴリズムを考えてみます。基本的な流れは次のようになります。
図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
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制御文]
このプログラム中に IF~END IFというのが出てきます。勘の良い方なら「ん?この構文は?FOR ~ NEXTやWHILE ~ WENDのように条件によってプログラムの実行順序を変える制御文かな?」と思ったことでしょう。その通りです。ただ、IF ~ END IFは繰り返し処理というより、条件によって処理内容が変わる選択処理に向いている制御文です。プログラミング言語によっては判断・分岐命令と呼ばれることもあります。IF ~ END IF制御文の使い方の基本はこうなります。
IF 条件式 THEN
条件式が成立したときに実行される命令
ELSE
条件式が成立しなかったときに実行される命令
END IF
ここで、条件が成立しなかった時に行なう処理が何もなければ、ELSE以下、END IFの手前までは省略できます(上のサンプルプログラムがそうです)。
さらに条件を細かく分けたいときには、このような使い方もできます。
IF 条件式1 THEN
条件式1が成立したときに実行される命令
ELSEIF 条件式2 THEN
条件式1が成立しないが、条件式2は成立したときに実行される命令
ELSE
条件式1も条件式2も成立しなかったときに実行される命令
END IF
これは少々わかりにくいと思いますので、実例でみてみましょう。次のプログラムでは入力された値が1か2か、それ以外かによって、処理の内容が変わっています。
PRINT "サービスデーのご案内"
INPUT "お客様の性別は 1.男性 2.女性",SEI
IF SEI=1 THEN
PRINT "毎週火曜日は男性のお客様は¥1000で食べ放題"
ELSEIF SEI=2 THEN
PRINT "毎週木曜日は女性のお客様は¥1000で食べ放題"
ELSE
PRINT "毎週水曜日は¥1000で食べ放題"
END IF
PRINT "焼肉 〇〇"
END
入力内容が1か2か、それ以外かで処理の流れがどのようになるか(この例では画面に表示される内容)、考えてみてください。実行結果は次のようになります。
条件によって処理内容が選択される
こんな焼肉屋さんがあったら、火・水曜日はいつもここで夕食ですなぁ(^ ^;
[この章のまとめ]
条件によって処理内容が変わる処理を選択処理という。
Tiny BASICでは選択処理に向いている制御文はIF ~ END IF制御文である。基本的な書き方は
IF 条件式 THEN
条件式が成立したときの処理内容
END IF
である。さらに条件を細かく分けたいときは
IF 条件式1 THEN
条件式1が成立したときの処理内容
ELSEIF 条件式2 THEN
条件式1は成立しないが、条件式2が成立したときの処理内容
END IF
【演習6】ユーザー認証のプログラムを作ってみましょう。登録ユーザーは2人で、登録した名前で認証するものとします(ここでは変数で入れておくことにしておきます)。ユーザー名を入力し、登録ユーザー名のどちらかと一致すれば「〇〇(登録ユーザー名)さん、こんにちは」どちらとも一致しなければ「認証できませんでした」と表示するようにすること。このプログラムはいろいろな方法があるのですが、習熟のため、IF制御文を使うようにしましょう。