H.switch文
switch文はif文同様分岐処理をしますが、場合分けが多数存在するときに便利です。
switch ( 式 ) {
 case 定数式1 :
  文1
  break;
 case 定数式2 :
  文2
  break;
 ・・・・
 case 定数式n :
  文n
  break;
 default:
  文n + 1
  break;
}

○「式」の値と等しい「定数式(=定数単体、またはそれらと演算子の並び)」に該当する「文」を、break文が出てくるか、switch文のブロックが終わるまで実行する
○「式」および「定数式」は整数型でなければならない
○「定数式1」〜「定数式n」のどれにも一致しないときにはdefault:以下が実行される
○default:は省略可能
○break文は省略可能だが、処理の流れに注意する必要がある

ここで、case 定数式: やdefault: のようにコロン「 : 」で終わる文ラベルと呼びます。ラベルはプログラムの行き先を指し示すための目印のように使われます。
この2つのラベルはswitch文のブロック内でのみ用いられ、ブロックの外からは参照できません。

[ 例 ] switch文の使用例  ex4-12.cGet! ソースファイル
int i; /* 変数の宣言 */

for (i=1; i<=5; i++) { /* iを1〜5まで変化させる */
 printf ("case[%d]: ", i);
 switch ( i ) { /* iの値で場合分け */
  case 1: /* i=1の時 */
   printf ("壱\n");
   break; /* break文があるのでswitch文から抜け出る */
  case 2: /* i=2の時 */
   printf ("弐\n");
   break; /* break文があるのでswitch文から抜け出る */
  case 3: /* i=3の時 */
   printf ("参\n");
   break; /* break文があるのでswitch文から抜け出る */
  default: /* それ以外の時 */
   printf ("壱〜参以外\n");
   break; /* break文があるのでswitch文から抜け出る */
 }
}

[ 例 ] switch文でbreak文を省略した例  ex4-13.cGet! ソースファイル
int i; /* 変数の宣言 */

for (i=0; i<=5; i++) { /* iを0〜5まで変化させる */
 printf ("case[%d]: ", i);
 switch ( i ) { /* iの値で場合分け */
  case 1: /* i=1の時 */
  case 3: /* i=3の時 */
  case 5: /* i=5の時 */
   printf ("%dは自然数かつ、奇数\n", i);
   break; /* break文があるのでswitch文から抜け出る */
  case 2: /* i=2の時 */
  case 4: /* i=4の時 */
   printf ("%dは自然数かつ、偶数\n", i);
   break; /* break文があるのでswitch文から抜け出る */
  default: /* それ以外の時 */
   printf ("%dは自然数ではない\n", i);
   break; /* break文があるのでswitch文から抜け出る */
 }
}

また、default:はスペルに注意しないといけません。下のプログラム例のようにdefalut:と記述してしまったとします。i が4,5のときにはdefault:処理が行われ"壱〜参以外"が表示されるはずです。ところが実行結果では何も表示されません。
これはスペルミスをしたため、defalut:はユーザーの定義したラベルとして扱われ、特殊な意味を持つdefault:ラベルとは認識されなかったのです。このようにスペルミスをしても基本的にエラーにならないので注意が必要です。ただ下のようなwarning(警告)はしてくれます。

ex4-14.c 25: Warning: label 'defalut' not used

これはソースファイル ex4-14.cの25行目で'defalut'というラベルは宣言されているが使われていない、という内容です。このように、コンパイル時に表示されるメッセージにはプログラムを修正するときに有用な情報も含まれているのでちゃんと確認するようにしましょう。

[ 例 ] default:をdefalut:としてしまった場合  ex4-14.cGet! ソースファイル
int i; /* 変数の宣言 */

for (i=1; i<=5; i++) { /* iを1〜5まで変化させる */
 printf ("case[%d]: ", i);
 switch ( i ) { /* iの値で場合分け */
  case 1: /* i=1の時 */
   printf ("壱");
   break; /* break文があるのでswitch文から抜け出る */
  case 2: /* i=2の時 */
   printf ("弐");
   break; /* break文があるのでswitch文から抜け出る */
  case 3: /* i=3の時 */
   printf ("参");
   break; /* break文があるのでswitch文から抜け出る */
  defalut: /* 綴りが違っているのでユーザー定義ラベルと見なされる */
   printf ("壱〜参以外");
   break; /* break文があるのでswitch文から抜け出る */
 }
 printf ("\n");
}

switch文はif文に書き換えられるますが、switch文の方がすっきり記述できるので複数の処理に振り分ける時にはswitch文を使うようにしましょう。
switch (a) {
 case 1:

  break;
 case 2:

  break;
 case 3:

  break;
 default:

  break;
}


if文に書き換えると・・・
if (a == 1) {

} else if (a == 2) {

} else if (a == 3) {

} else {

}

I.goto文


goto文は、指定されたラベルに無条件でジャンプする命令です。goto文でジャンプできる範囲は、同じ関数(6章で説明されます)の中だけです。
goto ラベル名;

ラベル名 :

goto文は構造化プログラムの考え方に合いません。goto文を多用すると、プログラムが分かりづらくなります。このため極力使わないのがよいのですが、入れ子になったループから一度に抜け出す場合などには有効です。
この場合goto文を使わないと、break分やフラグ(プログラムの状態を示す為の変数のこと)を使うことになり、より複雑なプログラムになります。

[ 例 ] goto文の使用例
int loop1,loop2; /* 変数の宣言 */

for (loop1=0; loop1<5; loop1++) {
 for (loop2=3; loop2>0; loop2--) {
  if (loop1-loop2 < 0) {
   goto error; /* goto文 error:ラベルの文までジャンプ */
  }
 }

error: /* ラベルの付いた文 */
printf ("-- 処理終了 --");

□ goto文を使わない場合

int loop1,loop2; /* 変数の宣言 */
int error = 0; /* フラグの宣言と初期化 */

for (loop1=0; loop1<5; loop1++) { /* ループ1 */
 for (loop2=3; loop2>0; loop2--) { /* ループ2 */
  if (loop1-loop2 < 0) {
   error = 1; /* フラグのセット */
    /* 1をセットすることでエラー状態を表す */
   break; /* ループ2を抜ける */
  }
  if (error == 1) { /* フラグのチェック */
   break; /* ループ1を抜ける */
  }
 }
printf ("-- 処理終了 --");


○ソースファイルのダウンロード○
この章に使った例のソースファイルを1つにまとめて圧縮してあります。
 【中に含まれているソースファイル】
  ex4-01.c ex4-02.c ex4-03.c ex4-04.c ex4-05.c ex4-06.c ex4-07.c
  ex4-08.c ex4-09.c ex4-10.c ex4-11.c ex4-12.c ex4-13.c ex4-14.c

ソースファイルのダウンロードexample04.lzh(5.1kBytes)


Jump to Phase #04-2Phase #04-2: 制御文(2) へ
Phase #05-1: 配列(1) へJump to Phase #05-1

△戻る
▲トップに戻る