分岐処理
順次処理
変数やConsole.Write()/Console.WriteLine()を用いれば、ある程度基本的な計算や画面への出漁が出来ます。しかし、プログラムとしてはいまひとつ物足りないというのも事実です。これまでやってきた処理は、プログラム中に記述された様々な処理を、その順番とおり実行するだけのものでした。こういった処理を、順次処理(じゅんじしょり)と言います。(図3-1)
分岐処理
しかし、プログラムは、順次処理だけでは出来上がりません。様々な状況に応じて、違った処理を行わなくてはなりません。例えばゲームプログラムを作っているとしたら「もし、敵に当たったらゲームオーバー」など といったような、条件に応じた処理の分岐が必要になります。こういったように、ある条件で処理の流れが変わる処理を、分岐処理(ぶんきしょり)と言います。(図3-2)
図3-1:順次処理 | 図3-2:分岐処理 |
---|---|
処理が順次実行される | 条件によって、処理の流れが変わる |
C#では、分岐処理を記述するための命令として、if(イフ)と、switch(スイッチ)という命令が用意されています。ここでは、それらについて解説します。
if文
サンプルプログラム
では、まず手始めに条件分岐の最も基本的な処理である、if文について学んでいくことにしましょう。ifとは、英語で、「もしも」という意味を表す単語で、「もしも~だったら、…する」といった処理を 行うために用います。まずは、以下のプログラムを実行してみてください。
プロジェクト:Sample301/ファイル名Program.csusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Sample301 { class Program { static void Main(string[] args) { // キーワードから数値を入力 Console.Write("整数値を入力:"); int a = int.Parse(Console.ReadLine()); Console.WriteLine("a="+a); // 入力した値が、正の数かどうかを調べる if(a > 0){ Console.WriteLine("aは正の数です。"); // 正の数だった場合に実行 } } } }
プログラムを実行すると、「整数値を入力:」と出ますので、ここでキーボードから数値を入力し、Enterボタンを押してください。まずは、正の値を入れてみましょう。すると、以下のようになります。
実行結果1.(正の値を入力した場合)a=10
aは正の数です。
すると、上のように「aは正の数です。」と表示されて、プログラムが終わります。続いて、同じプログラムで、負の値を入力してみましょう。すると、実行結果は以下のようになります。
実行結果2.(負の値を入力した場合)a=-5
実際に、何度か正の数や負の数を入力して試して見ましょう。正の数を入力したときだけ、「aは正の値です」というメッセージが表示されると思います。
コンソールからの入力
条件分岐について説明する前に、まずはコンソールからの文字入力について説明しましょう。15行目に、出ている、以下の表現は、コンソールからの文字列入力をおこないます。
コンソールからの文字列の入力しかし、この場合、入力知れた内容は、文字列を表す、string型のままです。そこで、入力した内容を整数の値に変換する必要があります。そこで、以下のようにして、その文字列を整数に変換します。
コンソールからの文字列を、数値に変換int.Parse()は、()内の文字列を、整数の値に入力する役割を果たします。したがって、文字列として整数の値が入力されれば、その値が整数の値に変換されます。しかし、それ以外の値が入力されると、エラーになり、メッセージが表示されます。
if文
続いて、なぜこのようにaの値によって結果が異なるのかについて説明します。このような結果が出るのは条件分岐で用いる、if文によるものです。if文は、次のような書式になっています。
if文の書式処理
}
()内の条件式が成立した時、{}に囲まれた処理を実行するのが、if文です。Sample301では、a>0、つまりaが0よりも大きい時に条件が成立し、{}内のprintf()文が実行されるわけです。 >は、比較演算子と言います。比較演算子は、以下のようなものがあります。(表3-1)
演算子 | 意味 | 使用例 |
---|---|---|
> | より大きい | a > 0 |
>= | 以上 | a >= 0 |
< | より小さい | a > 0 |
<= | 以下 | a <= 0 |
== | 等しい | a == 0 |
!= | 等しくない | a != 0 |
以上より、このプログラムが、キーボードから入力された数値が正の整数のときは「入力した値は、正の数です。」と表示され、そうでない場合は何も表示されないのです。 ただ、出来ることならば、正の数以外の値が入力された時にも何らかのメッセージを表示したいものです。そこで、次はそれをできる仕組みを紹介しましょう。(図3-3)
図3-3.Sample301のフローチャート |
---|
if~else文
サンプルプログラム
まずは、以下のプログラムを実行してみてください。
プロジェクト:Sample302/ファイル名Program.csusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Sample302 { class Program { static void Main(string[] args) { // キーワードから数値を入力 Console.Write("整数値を入力:"); int a = int.Parse(Console.ReadLine()); Console.WriteLine("a=" + a); // 入力した値が、正の数かどうかを調べる if (a > 0) { Console.WriteLine("aは正の数です。"); // 正の数だった場合に実行 } else { Console.WriteLine("aは正の数ではありません。"); } } } }
このプログラムの実行結果は、aに正の整数を代入した場合は変わりません。しかし、負の数を入力した場合は、以下のような実行結果になります。
実行結果(0および負の数をaに代入した場合)a=-5
aは正の数ではありません。
このように、if文の条件が成り立たない場合、実行されるのが、else以下に記述した文です。
else
ここで出現した、if~else文は、以下のような書式になっています。
if~else文の書式処理①
}else{
処理②
}
if文の()内の条件式が満たされた時には、処理①が実行されるのは、if文単体の時と変わりません。しかし、それ以外の場合、つまり条件式が満たされなかった場合は、else(エルス)文以下の処理②が実行されます。 したがって、このプログラムは、aが正の整数ではない、つまり、0か、負の値であるのならば、「入力した値は、正の数ではありません。」と出力されるのです。
図3-4.Sample302のフローチャート |
---|
else if
サンプルプログラム
ifとelseを用いた場合、ある条件が成り立つ場合と、そうでない場合の処理が書けました。しかし、実際には、条件が複数から成る場合も多く存在します。そういう時はどのようにすればよいのでしょうか?その時に役に立つのが、else if(エルスイフ)です。まずは、以下のサンプルを実行してみましょう。
プロジェクト:Sample303/ファイル名Program.csusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Sample303 { class Program { static void Main(string[] args) { // キーボードから数値を入力 Console.Write("1から3の整数を入力:"); int num = int.Parse(Console.ReadLine()); if(num == 1){ Console.WriteLine("one"); // numが1だった場合の処理 }else if(num == 2){ Console.WriteLine("two"); // numが2だった場合の処理 }else if(num == 3){ Console.WriteLine("three"); // numが3だった場合の処理 }else{ Console.WriteLine("不適切な値です。"); // それ以外の値が入力された場合の処理 } } } }
one
7行目のnumの値を、から、2,3に変更すると、表示される値は、それぞれ「two」、「three」と変化します。ただ、それ以外の値が代入されると以下のような結果になります。
実行結果2(それ以外の値がnumに代入された場合)不適切な値です。
else if
ifとelseだけでは、一つの条件が成り立った時と、それ以外の場合の処理しか実行できませんが、以上の結果のように、else ifを用いれば、複数の条件の場合についての場合分けが可能です。else ifを含むif文の書式は以下の通りになっています。
if~else if~else文の書式処理①
}else if(条件式②){
処理②
}else{
処理③
}
条件式①が成り立てば処理①が、条件式②が成り立てば処理②が実行され、そのどちらの条件も成り立たなければ、処理③が実行されます。なお、else ifは、ifの後に何個でも追加することができます。なので、いくつでも条件を追加することが可能です。
そのため、Sample303の処理の流れを記述すると、以下のようになるのです。(図3-5)
図3-5.Sample303のフローチャート |
---|
複雑なif文
サンプルプログラム
つぎは、これらの知識を組みあわせて、更に複雑なifの構文を作り上げてみましょう。まずは、以下のサンプルを実行してみてください。
プロジェクト:Sample304/ファイル名Program.csusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Sample304 { class Program { static void Main(string[] args) { // サイコロの目を入力 Console.Write("さいころの目(1~6):"); // コンソールから数値を入力 int dice = int.Parse(Console.ReadLine()); // 値が、サイコロの目の範囲内かどうかを調べる if(1 <= dice && dice <= 6){ // さいころの目が、偶数か、奇数かで、処理を分ける。 if(dice == 2 || dice == 4 || dice == 6){ Console.WriteLine("丁(チョウ)です。"); // 偶数ならば丁(チョウ) }else{ Console.WriteLine("半(ハン)です。"); // 奇数ならば半(ハン) } }else{ Console.WriteLine("範囲外の数値です。"); } } } }
このプログラムの実行すると、コンソールから数値を入力するように要求してきます、その値によって結果は、大きく分けて3通りに分けられます。まず一つ目が、1から6の間の偶数、つまり、2,4,6といった値を入力した場合です。以下のように、「丁(チョウ)です。」と表示され、プログラムは終了します。
実行結果1(2,4,6が入力された場合)丁(チョウ)です。
次に、同じく1から6の間で、今度は、1,3,5といった奇数を入力すると、「半(ハン)です。」と表示され、プログラムは終了します。
実行結果2(1,3の,5が入力された場合)半(ハン)です。
最後に、1から6以外の整数、つまりさいころの目に該当しないような7が出ると、「範囲外の数値です。」と表示されて、プログラムが終了します。
実行結果3(範囲外の数値が入力された場合)範囲外の数値です。
ネスト
さて、このプログラムを見ると、if文の中に、更にif文が入っています。これを、if文のネストと言います。ネストは、if文に限ったことではなく、この後紹介する繰り返し処理など でもしばしば見られる書式です。「何かの処理の中に、さらに何かの処理が入っているのがネストである」と理解すると良いでしょう。
if文のネストif(条件式②){
…
}
}
このように、if文はネストが可能ですが、二重、三重にネストをすることも可能です。ただ、あまりネストを多用すると、プログラムが複雑になり、わかりずらくなるので気をつけましょう。
論理演算子
また、次に注目したいのが、18行目および、20行目の、if文の中身です。ここでは、||や、&&が間に挟まって、複数の条件式が出ています。これらの記号は、論理演算子(ろんりえんざんし)と言い、if文などで複数の条件を調べるときには欠かせないものです。なお、C#言語で用いられる論理演算子は、以下のとおりです(表3-2)。
演算子 | 名称 | 意味 | 使用例 |
---|---|---|---|
&& | 論理積(ろんりせき) | AND(アンド) | a == 0 && b == 0 // aが0かつ、bが0ならば |
|| | 論理和(ろんりわ) | OR(オア) | a == 0 || a == 1 // aが0か1ならば |
! | 否定(ひてい) | NOT(ノット) | !(a == 0) // a==0でない場合、真となる |
例えば、&&は、AND(アンド)と言い、複数の条件がすべて成り立っているときに真となります。18行目の例で言うと、「変数diceの値が1以上であり、かつ6以下」ということになります。 また、||は、OR(オア)と言い、複数の条件のうち、どれかが成り立っているときに真、ということになります。20行目の例で言うと、「変数diceが2か、4か、6であれば」ということになります。
また、1から6の範囲の数値で、2,4,6以外の値となると、必然的に残りは、1,3,5となり、これが、「半(はん)」となることから、else文での処理は、「半(ハン)です。」と表示する ことになります。これら一連の流れの流れを記述すると、以下のようになるのです。(図3-6)
図3-6.Sample304のフローチャート |
---|
switch文
サンプルプログラム
Sample303のような、else ifを用いた多数に分岐する条件分岐は、値が整数値であれば、switch(スイッチ)文を用いて以下のように書くことができます。
プロジェクト:Sample305/ファイル名Program.csusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Sample305 { class Program { static void Main(string[] args) { // キーボードから数値を入力 Console.Write("1から3の整数を入力:"); int num = int.Parse(Console.ReadLine()); switch(num){ case 1: Console.WriteLine("one"); // numが1だった場合の処理 break; case 2: Console.WriteLine("two"); // numが2だった場合の処理 break; case 3: Console.WriteLine("three"); // numが3だった場合の処理 break; default: Console.WriteLine("不適切な値です。"); // それ以外の値が入力された場合の処理 break; } } } }
switch文は、後の()内の値によって、条件を分岐させる命令です。条件は、case(ケース)で書き、そのあとに値が来ます。最後にある、default(デフォルト)という条件は、 caseで出てきたいずれの条件にも当てはまらない場合を示しています。書式は、以下のようになります。
switch文
switch文の書式case 値①:
処理①
break;
case 値②:
処理②
break;
・・・
default:
処理③
break;
}
caseおよびswitchの後に出てくるbreak(ブレイク)というのは、処理の終了を意味します。switch文で作った分岐の処理の最後には、必ずこのbreakを入れるのを忘れないようにしましょう。
フォールスルーの禁止
このbreakを入れないで処理をフォールスルーと言います。フォールスルーを許可すると、例えば、以下のような処理がフォールスルーです。
フォールスルーの例case 1:
処理①;
case 2:
処理②;
break;
…
}
aの値が1の場合は処理①、処理②が、2の場合は処理②のみが実行されます。言語によってはこのフォールスルーを許可してますが、すでに説明した通りC#言語ではこのような処理を禁止しています。
複数の条件のcase
switch文で、複数のcase文で同じ処理をしたい場合の記述が許されています。次のサンプルを入力してみてください。
プロジェクト:Sample302/ファイル名Program.csusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Sample306 { class Program { static void Main(string[] args) { // サイコロの目を入力 Console.Write("さいころの目(1~6):"); // コンソールから数値を入力 int dice = int.Parse(Console.ReadLine()); switch (dice) { case 1: case 3: case 5: Console.WriteLine("丁(チョウ)です。"); // 偶数ならば丁(チョウ) break; case 2: case 4: case 6: Console.WriteLine("半(ハン)です。"); // 奇数ならば半(ハン) break; default: Console.WriteLine("範囲外の数値です。"); break; } } } }
実はこの処理はまったくSample304と同じ処理を行うものです。「丁(チョウ)です。」と表示する場合は、diceが1、3,5のいずれかですから、19行目から21行目までに至る3つのcase文を連続して記述することにより共通の処理が実行できるようになっています。
「半(ハン)です。」の場合も同様で、diceが2,4,6の場合も共通の処理が行えるようになっています。
練習問題 : 問題3.