条件によって処理を変える

プログラムは特に指示がない限り最初から最後に向かって順に処理をしていきます。でもそれではとても単純な仕事しかコンピューターにさせることができません。なので、プログラミング言語は処理の流れを変える仕組みを持っています。

if 文

今回は条件によって処理の流れを変える仕組みを説明しようと思います。では、簡単な例題プログラムを入力してみましょう。

now=Clock.Hour
if now >= 18 Then
  TextWindow.WriteLine("こんばんは")
EndIf

1行目のClock.Hourはこのプログラムを実行した時刻(時)を24時間制で表わしていています。変数 now に代入しているので、nowに現在時刻の何時何分の「何時」かの値が入っていることになります。

2行目の「if」というキーワードに注目しましょう。これは英語で「もしも〜」というような意味があって、仮定を表現する際に使われます。その後の「then」というキーワードは「〜であれば」くらいの意味があります。4行目の「EndIf (End If)」は英語ではちょっとこういう言い方はまずしませんが、敢えて日本語に直せば「仮定の話はここで終わり」くらいの意味です。
つまり、2行目から4行目までを敢えて日本語で表現してみると、こんな感じになります。

もし now >= 18 正しいようであれば、
  TextWindow.WriteLine("こんばんは") を実行しなさい。
仮定は終わり

つまり、例題の2行目の「if」と「then」の間の条件が正しい場合にだけ「if」文の直後から「endif」までの命令が実行され、条件が正しくない場合には直ちにendifの次の行に処理が移ります。今回の例題の場合、4行目のendifの後には命令がないので、そのままプログラムは終了します。ちなみに「>=」は、数学でいうところの「≧」と同じ意味です。つまり、プログラムを実行した時刻が18時(午後6時)以後であれば「こんばんは」と表示されますが、そうでない場合はなにも表示されません。if文とendif文の間には複数の命令を書くことができます。条件が正しければif文とendif文の間の全ての命令が実行されます。

else 文

でも、18時より以前になにも表示されないのは寂しいのでプログラムを下のように変更してみましょう。

now=Clock.Hour
If now > 18 Then
  TextWindow.WriteLine("こんばんは")
Else
  TextWindow.WriteLine("こんにちは")
EndIf

else」は英語で「〜そうでなければ」くらいの意味があります。つまり現在時刻が18時以降であれば「こんばんは」と表示されますが、そうでなければ「こんにちは」と表示されます。

複雑な if 文

でも、朝は「おはよう」と表示したいし、深夜には「こんばんは」と表示したいよね。なので、とりあえずまとめると次の表のようになるようにします。

4時〜11時 現在時刻 >= 4 かつ 現在時刻 < 11 おはよう
11時〜18時 現在時刻 >= 12 かつ 現在時刻 < 18 こんにちは
18時〜4時 現在時刻 >= 18 または 現在時刻 < 4 こんばんは

では、このように表示するようにプログラムを改造してみましょう。

now=Clock.Hour
If now >= 18 or now < 4 Then
  TextWindow.WriteLine("こんばんは")
ElseIf now >= 4 and now < 11 then
  TextWindow.WriteLine("おはよう")
Else
  TextWindow.WriteLine("こんにちは")
EndIf

4行目の「ElseIf(else if)」はelseとifを組み合わせた命令で、「〜そうでなく、しかも仮に〜であれば」くらいの意味になります。つまり、この例で説明すると、「2行目の条件が成り立たない場合であり、かつ4行目の条件が成り立つ場合」には、6行目のelse文までの命令が実行されます。elseif文は幾つも連ねることができます。

if 〜 then
   aaa
elseif 〜 then
   bbb
elseif 〜 then
   ccc
elseif 〜 then
   ddd
...
else
   zzz
endif

条件を先頭から確認していって、条件に合った場合にのみ特定の動きをプログラムにさせたいときにこのような構文が便利です。

ところで、2行目の条件がちょっと複雑です。

If now >= 18 or now < 4 Then

赤く色を付けた二つの箇所が二つの条件を表現しています。青色の「or」は「または〜」くらいの意味があります。つまり、2行目の例だと、「now が 18以上、または now が4未満の場合には...」という風な意味になります。

同じく4行目の「and」は「〜であり、かつ〜」という位の意味です。なので、4行目の例だと「now が4以上であり、かつ now が11未満の場合には...」という風な意味になります。

andやorを組み合わせることにより複雑な条件を指示することができますが、うまく組み合わせを表現するには少し練習がいるかもしれませんね。

字下げ(インデント)

ところで、例題の3行目や5行目の命令には先頭に空白(スペース)がいくつか入っています。Small Basicでは""でかこまれた文字列の中以外では空白は無視されます。なので、この空白はあってもなくてもどちらでも構いませんし、プログラムの実行にはなんの影響も及ぼしません。
じゃ、なぜ空白を入れるかと言うとそうするとプログラムが読みやすくなるからです。
こういう目的で使われている空白を「字下げ」とか「インデント」と呼びます。

例えば、If文はその終わりを示すEndIfと必ず対になっていますが、If文からEndifまでの一連の命令を塊として考えたほうがプログラムの内容を理解するときに理解しやすいことがあります。例としてIf/EndIfの中に入れ子になってIf/EndIfが書かれた場合を考えてみましょう。

下の例はif文が二重に入れ子になっているサンプルです。

now=Clock.Hour
If now >= 11 or now < 18 Then
  If now = 12 Then
    TextWindow.WriteLine("お昼だ!!")
  Else
    TextWindow.WriteLine("こんにちは")
  EndIf
EndIf

この例題のインデントをなくしても、プログラムは全く同じに動作します。

now=Clock.Hour
If now >= 11 or now < 18 Then
If now = 12 Then
TextWindow.WriteLine("お昼だ!!")
Else
TextWindow.WriteLine("こんにちは")
EndIf
EndIf

でも、見やすいのはどちらでしょうか?まぁ、入れ子が二重くらいであれば見やすさに違いはそれほどないかもしれないけれど、入れ子がもっと複雑になったり、If/EndIfの中の命令がもっとたくさんになってくると、下の例のようにインデントを一切入れないで書くとプログラムを読むときの見通しがとても悪くなってしまうのです。一方でインデントを入れた例では、どのくらい字下げを行っているかで対になるIf/EndIfがどれなのか、がとても分かりやすくなります。

というわけで、Small Basicに限らず近代的なプログラミング言語でプログラミングをする場合にはインデントをうまく使うようにする習慣があります。今回の例では空白を二つずつ行の頭に入れてインデントしていますが、いくつ空白を入れるかはプログラミング言語や、プログラムを作る人によって様々な習慣があって、どれが正しいといれるものでもありません。ただし、プログラムを読みやすくする為にプログラム全体にわたって決まったルールでインデントするようにしましょう。

文字列の判定

では次に次のようなサンプルを試してみましょう。

TextWindow.Write("お名前は? ")
name=TextWindow.Read()
If name = "たけし" Then
  TextWindow.ForegroundColor="blue"
EndIf
TextWindow.WriteLine(name+"さん、こんにちは")

2行目までは大丈夫だと思うけど、3行目のif文で、「name = "たけし"」という式があります。これは「変数nameの中身が"たけし"(ダブルコーテーションは含まない)と同じであれば」という条件式を表しています。つまり、if文の中では数だけでなく、文字列も比較することができるのです。

4行目ではTextWindow.ForegroundColorというまるで変数のようなものに"blue"という文字列を代入しています。このForegroundColorは「TextWindowのプロパティ」と呼ばれていてまるで変数のように使う事ができますが、Small Basicによって最初から用意されているものでTextWindowの性質を表現するための特別な変数のようなものです。TextWindowにはSmall Basicによって最初から用意されている(定義されている)このようなプロパティが幾つかありますが、後からプログラマーがプロパティを追加することはできません。

「Foreground Color」は「前景色」とでも訳せばよいのでしょうか。テキストウィンドーに表示される文字の色を表しています。「blue」はもう習ったかもしれないけど、色の「青」だよね。なので、「4行目は文字の色を青にしなさい」というような指示のための行になります。


もうひとつ6行目の「name+"さん、こんにちは"」が奇妙な点に気付きましたか?このnameという変数には2行目でプログラム実行時にキーボードから入力した文字列が入っているはずです。例えばキーボードから"あつし"と入力していた場合、ここは「"あつし"+"さん、こんにちは"」という式と同等となると思います。では、文字列と文字列を「足す(+)」とはいったいどういう意味なのでしょうか?

Small Basicでは文字列と文字列を足すと、二つの文字列を「連結する」という意味になります。つまり、この式の結果は「"あつしさん、こんにちは"」となるのです。じゃぁ、文字列同士の引き算や掛け算、割り算もあるのか、というと残念ながらそういう演算はできません。文字列同士の足し算はある種の便法のようなものなのですね*1

=(イコール)の話

さて、もし君が十分に注意深いならば前回の記事で等号記号/イコール(=)は変数への代入を表している、と説明されていたことを覚えているかと思います。ところが今回のif文の条件式の中で使われた = 記号はいわゆる等号、つまり = の左右の式が同じ値である、という条件を表現しています。

つまり何を言いたいかというと等号記号 = は、使われる場所によりその意味するところが異なってくるということです。これはとてもややっこしいので注意する必要があります。

整理しておくと、if文などの条件式で使われる = は等値関係の条件を表し、それ以外の場所で使われるときは変数やプロパティへの代入を表しています。

ちなみに等値関係は = ですが、「≧」は「>=」と表現し、「≦」は「<=」と表現します。「≠(等号否定)」は「<>」と表現します。つまり、

If(num <> 2) Then
  ....
EndIf

という条件式は「numが2と等しくなければ」という意味になります。

複雑なif文

And や Or を使い複雑な条件を表現することを説明したかと思いますが、次のサンプルの条件式をみてみましょう。四つの条件式が括弧やand/orで複雑に組み合わされています。これは文章にすると、「nameが"たけし"または"あつし"で、かつ、seibetsuが"男"または"おとこ"の場合」という意味になります。

TextWindow.Write("お名前は? ")
name=TextWindow.Read()
TextWindow.Write("性別は? ")
seibetsu=TextWindow.Read()
If ((seibetsu = "男") or (seibetsu = "おとこ")) and ((name = "たけし") or (name = "あつし")) Then
  TextWindow.ForegroundColor="blue"
EndIf
TextWindow.WriteLine(name+"さん、こんにちは")

「条件式Aまたは条件式B」という条件を表現する場合にはorというキーワードを使い、二つの条件を連結しましたが、この条件そのものが新たな条件式になることに気づくでしょうか?つまり、「条件式AB=条件式A or 条件式B」という関係がなりたちます。これはandでも同じです。そうすると今回の複雑な条件式は、「((条件式1[seibetsu = "男"]) or (条件式2[seibetsu = "おとこ"])) and ((条件式3[name = "たけし"]) or (条件式4[name = "あつし"]))」、つまり「((条件式1) or (条件式2)) and ((条件式3) or (条件式4))」と表現できますので、orで連結された条件式を整理すると「(条件式12) and (条件式34)」という意味になります。当然これもandで連結された条件式なので、新たな一つの条件式になります。

ところでやたらと括弧()で条件式を括っていたのはなぜなのでしょうか?

例えば「条件式A and 条件式B or 条件式C」という条件式があった場合、これは「条件AとBがともに成立するか、もしくは条件Cが成立する場合」という意味なのか、「条件BまたはCが成立し、さらに条件Aが成立する場合」という意味なのかはっきりとはわかりません*2。この条件式は「条件式A and (条件式B or 条件式C)」や「(条件式A and 条件式B) or 条件式C」と括弧を使ってまとめることができます。この場合の括弧は数学で使う括弧と似ていて「括弧の中を先に計算する(評価する)」ということを意味しています。つまり、「条件式A and (条件式B or 条件式C)」は「条件BまたはCが成立し、さらに条件Aが成立する場合」という意味であることがはっきりするのです。

まとめ

If文を使う事で条件によってプログラムの流れを変えることができます。条件は数が同じかどうか、大きいか小さいかを比較することができますし、文字列が同じかどうかを比較することもできます。

今日出てきた用語
インデント
プログラムを見やすくするために行の先頭に入れる空白のこと。この空白はSmall Basicから無視される。
文字列
一つの塊として扱われる文章、文字の集まりのこと。ダブルコーテーションで前後を挟んで表現されるが、そのダブルコーテーションそのものは文字列の一部としては扱われない。変数に代入することができる。

*1:実はSmall Basicでは文字列同士の引き算や掛け算をしてもエラーにはなりません。それぞれが数値0として扱われて引き算や掛け算が行われるようです。

*2:実はSmall Basicからするとルールがはっきりしているのでとても明確なのですが、人間が条件を読んだときにどちらを意味するか分かりにくい、ということが問題なのです