switch文

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索

switch文(スイッチぶん)とは、プログラミング言語において、ある式の値に応じて多分岐をおこなう文である。

最適化の仕方によって多少変わることはあるが、場合によってはテーブルジャンプなどにより、条件判断を繰り返すif文より効率的に実行される。

文法[編集]

C[編集]

構文は以下の通り。

switch (制御式) {
case1:
    文
    文
    ………
    break;
case2:
    文
    文
    ………
    break;
default:}

上記の「case」はいくつでも記述することができる。

この文は次のような手順で実行される。

  1. 制御式を評価し、整数値を得る。
  2. その整数値がどれかのcaseで指定された値であるなら、そのcaseに引き続く文に飛ぶ。
  3. どのcaseでも指定されていなければ、defaultに引き続く文に飛ぶ。
  4. もしdefaultが記述されていなければ、何も実行せずにswitch文を抜ける。

フォールスルー[編集]

ここで注意しなければならないのが、caseはラベルに過ぎず、そのcaseより前からの実行から、そこでswitch文を抜けさせる働きはない点である(一般的には、次のcaseがあらわれる直前にbreak文を置く)。このルールはフォールスルー(fall through)と言い、制御の流れが合流する動作をさせたい場合に便利であるが、一方でbreak文の書き忘れによるバグ、ループを抜けるbreakと取り違える誤読によるバグなど、バグの温床として問題視されてきた。

そのためlintでは、意図的にフォールスルーしていることを示す/* FALLTHROUGH */などのコメントが記述されていない限り警告を出す。また、Cに類似した構文を採用した言語でも、C#のように対策(後述)した言語仕様にされていることがある。

上記の例は、if文を羅列することで同様の動作を実現することができる。

_tmp_ = 制御式;
if (_tmp_ ==) {} else if (_tmp_ ==) {}
 
………
 
else {}

defaultは最後に記述される場合が多いが、必ずしも最後である必要はない。

switchによる分岐は以下のようにdo-while文と組み合わせることも可能である。

switch(count)
{
   default:       do {    printf("%d\n", count); count++;
   case 0:                printf("%d\n", count); count++;
   case 1:                printf("%d\n", count); count++;
   case 2:                printf("%d\n", count); count++;
                  } while (count);
}

例えばDuff's deviceではそのような使われ方をしている。

C#[編集]

C#では「goto case」が使える

switch (someInteger)
{
 case 0:
 case 1:
  return 1; // 変数someIntegerが0か1の時に実行
 
 case 2:
  someInteger++;
  goto case 3: // case 3も実行
 
 case 3:
  文A;
  break;
 
 default:
  文B;
  break;
}

C#では、文が1個も存在しない場合に限り、フォールスルーするcaseを書ける。文が存在するcaseでは、必ずbreakするか、goto caseしなければならない。goto caseにより、C言語ではフォールスルーを使って書くことができた、制御の合流を書くことができる。

C#では、CやC++が整数型しか制御式の値に使用できないのに対し、文字列型も使用できる。

Go[編集]

Goでは、caseに複数の値を指定できる。次のcaseの直前にfallthrough文を置くとフォールスルーになる。

PHP[編集]

PHPでは、C#と同様、文字列にも、switch文が適用できる。

switch (str) {
    case "ABC":
        文A;
        break;
    case "XYZ":
        文B;
        break;
    case "123":
        文C;
        break;
    default:
        文D;
        break;
}

BASIC[編集]

構造化されたBASICでは、Select Caseステートメントが存在することが多い。このステートメントでは、文字列または整数を対象にできる。

Select Case str
    Case "ABC"
        文A
    Case "XYZ"
        文B
    Case "123"
        文C
    Case Else
        文D
End Select
Select Case age
    Case Is < 20
        文A
    Case 20 To 29
        文B
    Case 30,50,70
        文C
    Case Else
        文D
End Select

Cなどと違い、各Caseはラベルではなく、Selectステートメントはフォールスルーでない。

Perl[編集]

Perlでは、perl-5.8以降からuse Switchとした上でswitch case文が使えるようになった。それ以前のバージョンのperlに関しては、Perl付属文章perlsynドキュメントのBasic BLOCKs and Switch Statementsの節に書式の例が書かれている。

Ruby[編集]

Rubyでは、case式により同様の多分岐ができる。フォールスルーはない。ラベルとして置いたものと条件値は===演算子で比較される[1][* 1]ため、これをオーバーロードすることでクラスに応じた一致判定を行うことができる。Ruby自体のクラスライブラリ内でも、正規表現の一致判定[2]、範囲オブジェクトでの範囲内かどうかの判定、オブジェクトがあるクラスに属するかの判定など、各種の定義がなされている。

脚注[編集]

脚注[編集]

  1. ^ なお、Rubyの===演算子は、JavaScriptやPHPでのような「厳密に等しい」という意味ではない。

出典[編集]

  1. ^ Ruby 1.9.3マニュアル - 制御構造、2014年3月3日閲覧。
  2. ^ Ruby 1.9.3マニュアル - class Regexp、2014年3月3日閲覧。

関連項目[編集]