【第6章】選択処理
2022.05.08
[選択処理]


図6-1.選択処理のイメージ

 前章で繰り返し処理について学びました。同じことを何回も繰り返し実行するというのはコンピュータの得意技です。繰り返し処理についてはまだまだお話したいことがあるのですが、このカテゴリーの目的のひとつに、短期間でプログラミング的思考を身につけるというのがあるので、繰り返し処理の続きは後の章で学ぶとして、ここはひとまず次の話題に進むことにします。

 昔話になりますが、管理人が小学校3年生のとき我が家に初めてカラーテレビが来ました。そのテレビは電源を入れた直後にマイコン制御で垂直同期が行われるようになっていたのですがテレピのボディに誇らし気に「人工頭脳付」というシールが貼ってありました。当時コンピュータは「人工頭脳」と呼ばれたものでした。今でも中国語では「電腦」(繁体)といいます。
 どうしてコンピュータが人間の脳に例えられるのかというと、コンピュータにはこれから学ぶ判断、処理の選択ができるという能力があるからです(もちろんそのようなプログラムが入っているからなのですが)。
 コンピュータが判断・処理の選択は、条件式が成立する(true)か成立しない(false)かで次の処理を実行するかどうかを決定する、というのが基本です(図6-1左)



 
                                                                                     

[偶数奇数判定プログラム]

 では。キーボードから入力された整数が偶数す奇数かを判定するプログラムを作ってみましょう。偶数とは2で割り切れる整数(0、2、4、6・・・)のことをいいます。対して奇数は2で割り切れない整数(1、3、5、7・・・)です。この判定を行なうには入力された数を2で割ってみて余りが出るかどうかをみればよいのですが、これをやるのにVB2022には便利な算術演算子がありましたね。そう、mod です。忘れてしまった方は第2章をもう一度見てください。
 プログラムの流れは図6-1右のようになります。


この流れにもとづいて作ったプログラムは次のようになります。

 1: Dim su As Integer
 2: Dim amari As Integer
 3: Console.Write(" 整数を入力してください ")
 4: su = Console.ReadLine()
 5: amari = su Mod 2
 6: If amari = 0 Then
 7:    Console.WriteLine("偶数です")
 8: Else
 9:    Console.WriteLine("奇数です")
10: End If
11: Console.ReadKey()

[プログラムの説明]

 1行目はキーボードから入力した整数を保存する変数、2行目は入力した整数を2で割った余りを代入する変数の宣言です。3行目は何を入力するかを表示し、4行目でキーボードから整数の入力を受けます。そして5行目は入力した整数を2で割った余りを求めるところです。
 次からが本章で中心になる判断・選択処理です。まず6行目です。If amari = 0 Thenとありますが、これは「もし、変数amariの値が0ならば次の処理を実行せよ」という意味です。どの処理を実行するのかというと7行目の「偶数です」と表示するところです。8行目の、Elseは「そうでなければ次の処理を実行せよ」という意味です。この場合なら9行目の「奇数です」と表示するところです。このようにIfとElseは条件が成立するかしないかで処理内容を分けるときに使いますが、どこまでが選択処理なのかということを示しているのが10行目のEnd Ifです。


[If 条件式 による処理の選択 ]
 If制御文の使い方をまとめておきます。最も基本的な使い方は
   If 条件式 Then
     条件が成立したときの処理(複数行でも可)
   End If
 これは条件が成立したときだけ特定の処理を行なう(条件が成立しないときは何もしない)場合です。

   If 条件式 Then
     条件が成立したときの処理(複数行でも可)
   Else
     条件が成立しなかったときの処理(複数行でも可)
   End If
 今のサンプルプログラムに出てきたもので、条件が成立するかしないかで処理内容を分ける場合です。


[条件式]
 選択処理や繰り返し処理の条件を指定する式を条件式といいます。条件式の書き方の基本を覚えましょう。
 条件式の書き方の基本的な形は
   式 比較演算子 式
です。条件式の場合、左辺は変数1個とは限りません。上のサンプルプログラムの6行目のamari = 0 は 0 = amari でもエラーにはなりません。あとはプログラムがわかりやすいかどうかです。そして条件式での = は代入演算子ではなく等号です。ややこしいですが早いところ慣れてください。
 VB2022で使える比較演算子は次のとおりです。



図6-3.VB2022の比較演算子

[条件が複数あるとき~論理演算子]

図6-4.複数の条件式がある場合

 条件式は1つではなく2つ以上書くこともできます。図6-4左を見てください。今、2つの条件式AとBがあるとします。条件式Aが成立する範囲はAとCです。そして条件式Bが成立するのはBとCです。そうするとCはA、B両方の条件式が成立する範囲ということになります。これを A And B と書きます。AかB、少なくともどちらか一方が成立する範囲はA、B、Cになります。これは A Or Bと書きます。Not は条件式が成立しない場合です。左の図で Not(A Or B) と書くと、Dの範囲になります。

この条件式と条件式を結ぶAnd、Or、Notのことを論理演算子といいます。VB2022で使える論理演算子はもっとあるのですが、この3つが基本になります。そして条件が成立することを真(True)、成立しないことを偽(False)といいます。

[Ifプロック]

 If~End IfまでのひとかたまりをIfブロックとよびます。Elseがある場合、Ifブロックの中はさらに2つのブロックに分かれます。それぞれのブロックは独立した部屋のようなものです。1つのブロックで1つのプログラムと考えてもけっこうです。これだけではさっぱりわからないと思いますので、実際のプログラムでみてみましょう。


[最小公倍数を求めるプログラム1]

 キーボードから入力した2つの整数aとbの最小公倍数を求めるプログラムを考えてみます。最小公倍数とは2つの整数の公倍数で共通するもののうちいちばん小さいものをいいます。ここでは小さい整数から順に2つの整数の公倍数かどうかを調べてゆくという方法をとります。整数a、bはせいぜい100くらいまで、調べる範囲は1~10000とします。プログラムの流れは下の図のようになります。



図6-5.最小公倍数を求めるプログラムの流れ


 この流れに基づいて作成したプログラムはこのようになります。

  1: Dim i As Integer
  2: Dim a As Integer
  3: Dim b As Integer
  4: Dim amari1 As Integer
  5: Dim amari2 As Integer
  6: Console.WriteLine("2つの数の最小公倍数を求める")
  7: Console.Write("1つめの数(整数) ") : a = Console.ReadLine()
  8: Console.Write("2つめの数(整数) ") : b = Console.ReadLine()
  9: For i = 1 To 10000
10:     amari1 = i Mod a
11:     If amari1 = 0 Then
12:        amari2 = i Mod b
13:        If amari2 = 0 Then
14:           Console.WriteLine()
15:           Console.WriteLine(i)
16:           Exit For
17:        End If
18:     End If
19: Next i
20: Console.ReadKey()

[プログラムの説明]

 今まで何回も出てきたところは省略し、要点だけに絞って説明します。
 9行目のForと19行目のNext iに囲まれた部分は整数1から10000までについて以下の処理(倍数かどうかを調べる)を繰り返しますという指示です。10行目は今調べている i の値 を整数aで割った余りを求めています。ここで余りが0でなければこれはaの倍数ではありませんからaとbの公倍数にはなり得ず以下の処理は不要となります。11行目のIfと18行目のEnd Ifに囲まれた中がIfプロックです。Ifブロックの中は独立した空間(この例の場合、aの倍数だけが入れる部屋と考えてください)ですから、この中にさらにIfブロックを置くこともできます。12行目では i の値をbで割った余りを求めます。
 ここで i はすでにaの倍数という条件はクリアしているのでさらにbの倍数でもあるという条件もクリアできていればこの i の値はaとbの公倍数ということになります。そして1から順番に調べていくうちに、最初にみつかった公倍数なのでこれが最小公倍数ということになります。このプログラムでは最小公倍数がみつかればあとの数について調べる必要はありません。16行目のExit Forは今入っているFor~Nextループから脱出せよ、という意味です。したがって最小公倍数がみつかれば20行目に移ってプログラム終了です。このようにForとIfを組み合わせて使うと、ある条件を満たしたら繰り返し処理終了という流れが作れます。


[最小公倍数を求めるプログラム2]

このプログラムは2つの整数の最小公倍数を求めるものなので、論理演算子Andを使って次のように書くこともできます。


  1: Dim i As Integer 
  2: Dim a As Integer
  3: Dim b As Integer
  4: Dim amari1 As Integer
  5: Dim amari2 As Integer
  6: Console.WriteLine("2つの数の最小公倍数を求める")
  7: Console.Write("1つめの数(整数) ") : a = Console.ReadLine()
  8: Console.Write("2つめの数(整数) ") : b = Console.ReadLine()
  9: For i = 1 To 10000
10:    amari1 = i Mod a
11:    amari2 = i Mod b
12:    If amari1 = 0 And amari2 = 0 Then
13:       Console.WriteLine()
14:       Console.WriteLine(i)
15:       Exit For
16:    End If
17: Next
18: Console.ReadKey()

 このプログラムでは10、11行目でa、bで割った余りを求め、12行目でa、bの公倍数かどうかをいっぺんで判定しています。論理演算子を使うとこのようにIfブロックの中にまたIfブロックということをしなくてプログラムの行数も少なくて済みます。どちらの形で書くかはプログラムへの要求によって異なってきます。

[演習3]三択クイズのプログラム
簡単な三択クイズを作ってみましょう。問題文の選択肢を表示し、答えを番号で入力、正解なら「正解です」と不正解なら「残念でした」と表示することにします(図6-6参照)。


図6-6.三択クイズのプログラム実行画面

[コラム]コンピュータは忠実過ぎる部下
 ここまでプログラミングをやってきた皆さんは、コンピュータは自分が作ったプログラムに従って忠実に動く部下のようにみえてきたことと思います。たしかにコンピュータは皆さんが指示したとおりの仕事を「疲れた~」とか「めんどくせ~」とか文句言わずにこなしてくれます。ただコンピュータは忠実過ぎて少々融通がきかないという面もあります。たとえば皆さんがプログラムを作って実行しようとしたところこのような画面になって実行できなかったということがあったりしませんでしたか。


図6-7.文法エラー

 プログラミング言語には「言語」というくらいですから文法があります。文法といっても主語とか述語というものではなく、プログラムの書き方のルールのことです。図6-7ではConsole.Writelineと書かなくてはならないところがdonsole.Writelineになっているので、コンピュータが???になってしまい実行できないのです。「こんなの1文字タイプミスしただけ。見りゃConsoleだってわかるだろが」と言いたいところですが、それをコンピュータに求めるのは無理なのです。このようなプログラムの書き方の間違いによるエラーを文法エラーといいます。


図6-8.実行時エラー

 プログラミング言語の文法どおりに書かれていればコンピュータはそれを忠実に実行しようとします。たとえ行く手に落とし穴があったとしてもです。図6-8のプログラムは文法どおりに書かれていますが、分母が0の割り算をやってしまっています。算数でも割る数が0の割り算は「不能」になりますが、コンピュータでも同じで扱えないデータが入ってきたり扱えない演算を実行しようとすると実行時エラーとなります。「計算できないとわかっているならその手前で止まれよ」と言いたくなりますが、これも無理です。そうしたいのならそのようにプログラムを組まなくてはなりません。


図6-9.論理エラー

 文法も間違いない、あり得ないデータも入ってこない、無理な演算もない、それでも発生するエラーがあります。それは論理エラーといい、プログラム中の命令や式にミスがあって正しい結果が得られない、というものです。論理エラーのやっかいなところは文法エラーや実行時エラーのようにエラーが発生したところでコンピュータが止まらないことです。なのでプログラムのミスをさがすのに大変苦労します。図6-9のプログラムは半径10の円の面積を求めるもののつもりなのですが、結果が間違っています(314.159になるはずです)。これは円の面積を計算するところで、S = pai * r ^ 2(またはS = pai * r * r)とすべきところをS = pai * r * 2としてしまっているためです(ちなみにこれだと円周の長さになってしまいます)。
 コンピュータによる計算、処理が正確だというのはプログラムやデータが正しく与えられている場合のことであり、これらが誤っていれば、間違った処理結果が出てしまったり途中で止まってしまったりします。

[昔はよかったなぁ]

 最小公倍数を求めるプログラム1を昔のBASICで書くと次のようになります。

図6-10.最小公倍数を求めるプログラムを昔のBASICで書くと

 昔のBASICではIfの後ろのEnd Ifというのがありませんでした。書かなくていいならラッキー!と思ってしまいそうですが、ちょっと待ってください。End IfがないということはIfブロックもないということです。条件が成立したときに行なう処理が複数行ある場合には、↑のプログラムの行番号60のようにthenの後ろに : で区切って複数の処理を書き連ねてゆくことになります。ここで条件が成立したときの処理が100行あったらどうなるでしょう。thenの後ろに : で区切られた処理が連なることになり大変見辛いプログラムになります。

- CafeNote -