Previous: 繰り返し
Up: 制御構造 II
Next: 復習
Previous Page: 繰り返し
Next Page: 復習

判断

判断については、我々は、if - else if - else 文を学習したが、多くの 選択子の中から選ぶ場合、if 文の構文はいささか面倒である。 例えば、次のような if 文による選択を考えてみる。

例1
        if ( input == 'h' ){
            x--;
        }else if ( input == 'j' ){
            y++;
        }else if ( input == 'k' ){
            y--;
        }else if ( input == 'l' ){
            x++;
        }

このプログラムでは、文字型の変数 input にキーボードから読みとった 文字の値が入っていて、それが 'h' だったら変数 x を一つ減らす、 'j' だったら変数 y を一つ増やすというような判断を行っている。 要するに、文字型変数 input の値によって対応する処理を行っているだけ なのだが、いちいち else if を用いて、input== という判断を しなければならないので、面倒であるし、ソースコードも見づらい。そこで、 こうした処理を簡単に書くための構文が用意されている。この新しい構文は、 switch - case 文あるいは簡単に switch 文( case 文と言う 事もある)と言い、上の例ならば、 次のように書くことが出来る。

例2(例1に同じ)
        switch(input){
            case 'h':   x--; break;
            case 'j':   y++; break;
            case 'k':   y--; break;
            case 'l':   x++; break;
        }

すなわち、switch に続く () の中に指定した変数の値について、 'h' ならば( case 'h': )、次に続く文を実行する。ここで、注意 するのは、break; である。これは、switch 文を抜けるための指示で ある。もし、break; がなければ、つぎの case 文の後の実行文に制御が移る。 いちいち、break; とするのは面倒なようだが、実はこれは非常に 便利なことがあるために、わざわざこうなっている。何故そうなっているのか、 次の例を見てみよう。

例3
        switch(input){
            case 'h':   x--; break;
            case 'H':   x--; break;
            case 'j':   y++; break;
            case 'J':   y++; break;
            case 'k':   y--; break;
            case 'K':   y--; break;
            case 'l':   x++; break;
            case 'L':   x++; break;
        }

この例では、入力文字が 'h' の場合と、'H' の場合とでは、同じ 処理を行っている。同じ処理を行うものはまとめて書いておけば便利であろう。 ここで、先の break; の説明を思い出して欲しい。break; がなければ、 次の case 文の後の実行文に移るのであるから、上の例は、次のように簡潔に 書くことが出来る。

例4(例3に同じ)
        switch(input){
            case 'h':
            case 'H':   x--; break;
            case 'j':
            case 'J':   y++; break;
            case 'k':
            case 'K':   y--; break;
            case 'l':
            case 'L':   x++; break;
        }

勿論、2行を一つの行にまとめて、次のように書いても良い。

例5(例4に同じ)
        switch(input){
            case 'h': case 'H':     x--; break;
            case 'j': case 'J':     y++; break;
            case 'k': case 'K':     y--; break;
            case 'l': case 'L':     x++; break;
        }

もしこれを if 文を用いて書いたならば、

例6(例5と同じ)
        if ( input == 'h' || input == 'H' ){
            x--;
        }else if ( input == 'j' || input == 'J' ){
            y++;
        }else if ( input == 'k' || input == 'K' ){
            y--;
        }else if ( input == 'l' || input == 'L' ){
            x++;
        }

のように、かなり見づらく長いプログラムになる。

さて、switch 文の威力が分かったところで、switch 文の書式を まとめよう。

switch - case 文の書式

switch ( 整数値をとる式 ){ case 定数値 : 実行文; case 定数値 : 実行文; ... [default:] 実行文; }

switch 文は便利だが、整数値を持つ式にしか使えない点に注意しよう。 C 言語では、文字も整数値を持つので、整数型と文字型にしか使えず、それが、 ある定数に一致するような場合にしか使用できない。また、case の後の 値は、定数でなければならないので、変数を使用することは出来ない(そのような 場合は、if 文を使うしかない)。

上の書式には、新しく default という文があるが、これは、if 文で 言うところの else に相当するもので、他の case のどれにも当ては まらない場合には、この default 以下の実行文が実行される。

switch 文で注意するのは、例4、5のようにわざと2つの case 文を つなげる場合以外は、必ず、break; で終わるようにする点である。 ( default: の場合もそうする。)文法的には、最後の ( } の直前の )case または default は、break; 文がなくても、switch 文から抜けるので良いように思われるが、この場合でも 後から case 文を付け足すことも考えて、常に break; 文を書く習慣 をつけておいた方が良い。

課題14

cd c を実行した後で( /c に移動した後で)、以下の課題を やってみよ。

課題 14.1
while を使ってみる

以下のプログラムを while 文を用いて書き換えよ。

#include <stdio.h>
main()
{
    int i=1, sum=0;

for (; i<10; i++){ sum += i; } }

課題 14.2
switch 文を使ってみる

以下のプログラムを switch 文を用いて書き換えよ。

#include <stdio.h>

int GetInput(int);

main() { int input, cont;

while(1){ fflush(stdin); printf("適当な数字を入力せよ。0 ならば終わり => "); scanf("%d", &input); cont = GetInput(input); if (cont==0){ break; } printf("result %d\n", cont); } }

int GetInput(int input){ int result;

if ( input == 1 ){ result = 1; }else if ( input == 2 ){ result = 2; }else if ( input == 3 || input == 4 ){ result = 3; }else if ( input == 0 ){ result = 0; }else{ result = 4; }

return result; }

課題 14.3
ロールプレイングゲーム II

課題 13.2 のプログラムを、switch, while を用いて、書き換えよ。 書き換えた関数をメイルで金山まで送ること。但し、メイン関数を書き換えた場合は、 メイン関数を送ること。書き換えていない関数は、送らない事。 題は kadai14 とすること。

プログラム全体は大きいので、送らないこと。

maruyama@wakhok.ac.jp
1995年02月08日 (水) 18時57分57秒 JST