★分岐構造:switch文2★
まずはswitch文の使い道の一つを紹介しましょう。
switch文は、1つの変数の中身を調べ、値によって処理を分けるという形をとっています。
そのため、メニュー選択に使われる場合があります。
下に適当な例を書きます。(これだけでは、使い物になりませんが・・・)
<sample program 019-01>
#include <stdio.h>
int main( void )
{
int menu;
printf( "メニューを選択してください:\n" );
printf( "0:開始\n1:終了\n" );
scanf( "%d", &menu );
switch( menu ) {
case 0:
printf( "開始!\n" );
break;
case 1:
printf( "終了!\n" );
break;
}
return 0;
}
|
<実行結果1 VC++ Express Edition>
メニューを選択してください:0
開始!
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
メニューを選択してください:1
終了!
続行するには何かキーを押してください・・・
<実行結果3 VC++ Express Edition>
メニューを選択してください:2
続行するには何かキーを押してください・・・
<実行結果4 VC++ Express Edition>
0から4までの整数を入力してください:-1
続行するには何かキーを押してください・・・
当然、開始と終了だけではないケースも十分考えられますが、前回同様メニューを増やしたい場合、caseラベルを増やせばよいのです。
また、前回は流していましたが、テストの際に、caseラベルにない数値も入力しています。
テストするためには、正しいデータのみ入力してはならないことは書きました。
面倒だと思わず、必ず試してみてください。試してみると色々と疑問も浮かんでくるはずです。その時こそ、あなた自身の身になる学習になるのです。
さて、ここでswitch文でよくある間違いについて、書いておきましょう。
<sample program 019-02>
#include <stdio.h>
int main( void )
{
int menu;
printf( "メニューを選択してください\n" );
printf( "0:開始\n1:終了\n" );
scanf( "%d", &menu );
switch( menu ) {
case 0;
printf( "開始!\n" );
break;
case 1;
printf( "終了!\n" );
break;
}
return 0;
}
|
どこが間違っているか分かりますか?
良く見て考えてください。
実行結果を書きます。
<実行結果 VC++ Express Edition>
main.cpp(14) : error C2143: 構文エラー : ':' が ';' の前にありません。
main.cpp(17) : error C2143: 構文エラー : ':' が ';' の前にありません。
caseラベルの後ろは、「:(コロン)」です。
すでに、実際に打ち込んだ際に、間違った方もいるかも知れません。
このケースでは、「:(コロン)」ではなく、「;(セミコロン)」を打ち込んでいます。
ですから、エラーメッセージに「':' が ';' の前にありません。」とあるのです。
次の例です。
<sample program 019-03>
#include <stdio.h>
int main( void )
{
int menu;
printf( "メニューを選択してください\n" );
printf( "0:開始\n1:終了\n" );
scanf( "%d", &menu );
switch( menu ) {
case 0:
printf( "開始!\n" );
case 1:
printf( "終了!\n" );
break;
}
return 0;
}
|
何となくおかしい箇所には気づいたかも知れませんが、実行結果はどうなるのでしょうか?
まずは、頭で考えてみて、実際に打ち込み、実行結果と照らし合わせて見ましょう。
先に打ち込んでみて、実行結果から類推するという方法もありますが、ここでは先に考えてみてください。
ヒント:breakの役割を覚えていれば、何となく想像できるでしょうか。
<実行結果1 VC++ Express Edition>
メニューを選択してください:0
開始!
終了!
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
メニューを選択してください:1
終了!
続行するには何かキーを押してください・・・
<実行結果3 VC++ Express Edition>
メニューを選択してください:2
続行するには何かキーを押してください・・・
<実行結果4 VC++ Express Edition>
0から4までの整数を入力してください:-1
続行するには何かキーを押してください・・・
実行結果1に注目してください。
「開始!」と「終了!」が両方表示されています。
ヒントにも書きましたが、breakの役割とは、「switch文を抜ける」ことです。
そして、caseラベル0の部分にはbreakがありません。
breakが無いということは、「switch文を抜けない」ということです。
「switch文を抜けない」から、caseラベル0の実行後、そのままcaseラベル1を実行してしまうのです。
caseラベル1にはbreakがありますから、実行後switch文から抜けています。
では、breakがまったく無ければ「switch文から抜けられない」のでしょうか?
※こういった疑問が「すっ」と出てくると良い兆候です。試せる環境があるのですから、どんどん試してください。
<sample program 019-04>
#include <stdio.h>
int main( void )
{
int menu;
printf( "メニューを選択してください\n" );
printf( "0:開始\n1:終了\n" );
scanf( "%d", &menu );
switch( menu ) {
case 0:
printf( "開始!\n" );
case 1:
printf( "終了!\n" );
}
return 0;
}
|
<実行結果1 VC++ Express Edition>
メニューを選択してください:0
開始!
終了!
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
メニューを選択してください:1
終了!
続行するには何かキーを押してください・・・
<実行結果3 VC++ Express Edition>
メニューを選択してください:2
続行するには何かキーを押してください・・・
<実行結果4 VC++ Express Edition>
0から4までの整数を入力してください:-1
続行するには何かキーを押してください・・・
<sample program 019-03>の実行結果とまったく同じです。
これは、基本制御文の最初に書いた「順次」という考え方で、基本的にはプログラムは上から下へ向けて実行されます。
caseラベル1の実行後は、すぐ下の「}」へ行き、そのままswitch文を抜けます。
では、最後のbreakは書いても書かなくても同じということなのでしょうか?
実際は、同じです。
が、上にも書きましたが、メニュー等を追加したい場合も出てきます。
例えばcaseラベル2等を追加する場合に、caseラベル1にbreak文を付け忘れたらどうしましょうか・・・
忘れるわけが無い!と思われる方もいらっしゃるかもしれませんが、良く忘れるのです。
プログラムが複雑になればなるほど、色々な箇所でエラーが発生したり、思ったとおりに動かなくなるのです。
原因はいろいろあると思いますが、「ついうっかり」とか「面倒だから後回しにしよう」と思った箇所を忘れていてエラーになることが山ほどあります。
エラーを予防するプログラムは非常に重要な意味を持っています。
無駄と思わず、必ず書くようにしましょう。
break;と6文字打つのを省略して、エラーチェックにタイピングの何倍もの時間をかけるのは避けたいですね。