選択文(2) switchとその他
もう一つの選択文
switch文はif文と同じ区分で、選択文です。 if文と比べて少々制約が多く、高度な条件分岐と言えます。 ともあれ詳しい説明は後にして、次のプログラムを見てください。
var a=3; if ( a==1 ) { System.inform("aの値は1です"); } else if ( a==2 ) { System.inform("aの値は2です"); } else if ( a==3 ) { System.inform("aの値は3です"); } else { System.inform("aの値は分かりません"); }
これは、変数aの値を表示するだけのプログラムです。 この文は次のように書ける事はこれまでの知識で分かると思います。
System.inform("aの値は"+a+"です");
ですが、あえて選択文を使って説明する事にします。
このプログラムを眺めていると、ある共通点が浮かびますよね。 そう、条件式に使用している変数は全て「変数a」なのです。 「変数a」が1なら、「変数a」が2なら……。
このように、比較する対象の変数が一つであるならば、 switch文を使うほうがスマートに記述する事が出来ます。
switch文の基本
まずは基本的なswitch文の書式を見てみましょう。
switch (比較する変数) { case 定数1: // 「比較する変数」と「定数1」が一致したら処理 break; }
- switch()の括弧の中に比較したい変数を記述します。 if文と同様に、{}を忘れないようにしてください。
- 次に、caseに続いて比較する定数を書きます。
(caseの後に半角スペースを書かないとエラーになります。 同じく、最後にコロン(:)を忘れずに。) - 処理の最後に「break;」を書いて終わりです。 breakは{}のブロックを抜けるという機能がありますので、 希望する処理が終わった時点で書いておくと、そこでswitch文の処理を終えます。
このように、if文と違い、switch文では一定の値との比較しか出来ません。 また、switchの後の括弧()の中は、if文と違って条件式を書くのでは無い事に注意してください。
もちろん、比較する定数は追加する事も出来ます。
switch (比較する変数) { case 定数1: // 「比較する変数」と「定数1」が一致したら処理 break; case 定数2: // 「比較する変数」と「定数2」が一致したら処理 break; }
もし、どの値とも一致しなかった場合に何かしらの処理をさせたい場合、 defaultを追加します。これはif文の「else」に相当します
switch (比較する変数) { case 定数1: // 「比較する変数」と「定数1」が一致したら処理 break; case 定数2: // 「比較する変数」と「定数2」が一致したら処理 break; default: // どの定数とも一致しなかったら処理 break; }
これがswitch文の基本形です。
switch文の利用例
では、最初に示した変数aの値を表示するプログラムを、 switch文で書き直してみましょう。
var a=3; //変数aと比較していく switch (a) { case 1://変数aが1なら… System.inform("aの値は1です"); break; //変数aが1では無く2なら…(if文の else ifのようなもの) case 2: System.inform("aの値は2です"); break; case 3://変数aが3なら… System.inform("aの値は3です"); break; default://変数aが一致しなければ… System.inform("aの値は分かりません"); break; }
この書き方では、if文と比べて、変数aがどの値と比較しているのかが、一目で分かりやすくなっていますね。 ですから一つの値とある値を比較するだけならば、 switch文を使った方が読みやすいプログラムとなります。
switch文の使用例(2)
switch文には、いくつか省略出来る項目があります。 一つは「default」の部分がありましたよね。他にもう二つあるので紹介しておきます。
breakの省略
最初に説明した通り、「case 比較する定数:」の後に「break;」を書くと、 ここでswitch文の処理を抜けるという効果があります。 したがって、breakが登場するとswitchの処理は終了します。 逆に言えば、breakを書かなければ処理は継続するという事です。
例えば、以下のプログラムを実行してみてください。
var a=1; switch (a) { case 1://変数aが1なら… System.inform("aの値は1です"); //ここに書くはずの break;を省略 case 2://変数aが2なら… System.inform("aの値は2です"); case 3://変数aが3なら… System.inform("aの値は3です"); }
実行結果はいかがでしたか? 変数aの値は1ですから「aの値は1です」と表示されるのは当然としても、 その後のcase 2、case 3も同様に処理されてしまいましたね。 これがbreak;を省略した事による効果(時には不具合)です。
プログラムによっては、直後の処理も行わせたい場面が出てくるかもしれませんので、 breakを使わない事による影響を知った上で省略する、という使い方もあります。
処理の省略
処理の省略とは、以下のようなものです。
var a=1; switch (a) { case 1://変数aが1なら… case 2://変数aが2なら… System.inform("aの値は1か2です"); break; case 3://変数aが3なら… System.inform("aの値は3です"); }
ここでは「case 1:」、つまり変数aの値が1の時の処理を省略しています。 break;も省略しているので、次の処理も行われます。 よって、結果的にaの値が1か2の時に「case 2:」の処理が行われます。 ようはif文で説明した論理演算子「||」のような分岐になったのです。
その他の使用例
switch文には、まだ様々な使い方があります。 ある定数との比較しか出来ない、でも奥が深い。この辺りが高度な選択文らしさなのかもしれません。
その用途全てを説明する事は出来ませんので、 最後に二つの説明を加えて終わりたいと思います。
文字列との比較
今まで比較する定数は数値の1や2を使用していましたが、 文字列と比較する事も出来ます。
var a="あいうえお"; switch (a) { case "あいうえお"://変数aが「あいうえお」なら… System.inform("あいうえおです"); break; case "かきくけこ"://変数aが「かきくけこ」なら… System.inform("かきくけこです"); break; }
これをif文で表現すると以下になります。
var a="あいうえお"; if ( a == "あいうえお" ) { System.inform("あいうえおです"); } else if ( a == "かきくけこ" ) { System.inform("かきくけこです"); }
式を比較対象とする
最後に重要な点を説明します。 これまでswitchの括弧()には、比較する変数を指定する、としてきました。 これ自体は間違いではないのですが、正確には式を指定します。
式とは「値を持つもの」のような意味という事を以前に説明した通り、 結果的に値を返すものであれば、何を指定しても構いません。
switch ( 式 ) { …処理… }
ですから、以下の指定は全てOKという事になります。
switch ( a=b ) …aにbを代入した結果と比較(変数aと比較)
switch ( a*2-5 ) …「a*2-5」の演算結果と比較
switch ( a==b ) …「a==b」が返す値と比較(真または偽)
以前に四則演算のところで、 演算式は値を返す、というコラムを紹介していますが覚えていますか?
「演算式は代入以外の場面でも使える」という事が、 このような場面で活用できるわけですね。
基本的には、switch文を使用する際には、 ある変数と比較するのが一般的ですし、中には実用性の無いものもあります。 しかし、式を指定するという事を知っていると、 本格的なプログラムを作るようになってから役に立つかもしれません。
その他の選択文
選択文の締めくくりとして、似たような命令を二つ紹介します。 これらは扱いが少々難しいので、 慣れないうちはif文やswitch文を使うようにしてください。
演算子 if
if…どこかで見た事があります。 でも、選択文のif文とは別物ですので混乱しないようにしてくださいね。 リファレンスには以下のように書かれています。
if 演算子 if は、右側にあるものを評価した結果が真の場合のみに、左側にあるものを評価する演算子です。
つまり、こういう事です。
[処理内容] if ここが真なら[処理内容]を行う
例えば…
a = 1 if a < 1…変数aが1より小さければaに1を代入する
if演算子は値を返さない?
通常、演算子を使用した式は値を返しますが、 リファレンスには以下の注意書きがあります。
演算子の結果を得ることはできません
つまり「a = 1 if a < 1」は値を持たない、という事になります。 ですから以下の書き方は誤りです。
System.inform(a = 1 if a < 1);
if文で処理するよりも簡単に記述出来る反面、 コメントなどで追記しておかないと、分かりづらいデメリットもあります。 基本的に、プログラムでの選択文は重大な不具合になりえますので、 よく注意して使用しましょう。
三項演算子 ?
三項演算子「?」もif演算子と同様に、 ある式が真ならある処理を行う、というものです。 違いは演算子全体として「値を返す」事と「偽の処理が行える」事です。 書式は以下のようになります。
条件式 ? 式が真の時の処理 : 偽の時の処理;
ただ、視覚的に分かりやすくする為に、条件式は括弧で囲む事が多いです。
( 条件式 ) ? 式が真の時の処理 : 偽の時の処理;
こう見ると、if文やswitch文と比べても分かりやすくなりますね。 返す値は処理した結果……つまり「式が真の時の処理の結果」または「偽の時の処理の結果」になります。
三項演算子は、一般的に代入の時に使われる事が多いです。 これも、if文などで記述するよりも簡単という事が理由なのですが、 やはり視覚的に(if文と比べて)分かりづらいので、無理に使う必要はありません。
//三項演算子の代入使用例 var a=100; var b=200; // 変数aが変数bより大きければ1、そうで無ければ2を変数aに代入 a = (a > b) ? 1 : 2; // 変数aが変数bより小さければa、そうで無ければbに2を代入 (a < b) ? a : b = 2;
三項演算は式、なので複数個を組み合わせてif文のelse ifの代用として使う事も出来ます。 が、とても読みづらいプログラムになるのでお勧めはしません。 ただ、このような書き方をしているプログラムもたまに見かけるので、 知識の一つとして覚えておいて損はありません。
a = (a < b) ? 1 : (a > b) ? 2 : 3;
順番に見ていきましょう。
- 最初に(a < b)を評価します。真なら1を返します。
- 偽だった場合。:の右側の評価を行います。 ここの処理は(a > b) ? 2 : 3です。
- (a > b)を評価します。真なら2を返します。偽なら3を返します。
- 返された値を変数aに代入します
これをif文に直すと次のようになります。
var a=200; var b=100; if (a < b) { a=1; } else if (a > b) { a=2; } else { a=3; }
縦に長くなってしまいますが、比較している数値がとても分かりやすいですね。 ですから、代入に使うならif文を使うほうが、不具合もグッと減るはずです。