70 プ C8 C + + ス門 7. え 5 3 つ以上の場合分けノ switch 3 つ以上の場合分けをしたいときに , else if を使いますが , もし 5 つも 6 つ もの場合分けをしたいときを考えてください . たしかに elseif をいくつも使っ て書くことはできますが , あまり見栄えのよいプログラムとはいえなくなるで しよう . C では , elseif の他に switch という条件文を使うことができます . この条 件文は , switch, case, default の 3 つを使って , 次のように書きます . switch ( 式 ) { case 定数 1 : 文 文 break; case 定数 2 : 文 文 break; default: ( ) で囲まれた式の値が , case に続く定数 ( 結果が定数となる式なら定数 でなくてもよい ) と一致すると , それぞれの文を実行します . この switch 文は , if 文と違い , { } で囲まなくてもいくつもの文を実行でき ます . default: の部分は , どの case にもあてはまらないときに実行する処理 を書きます . この default 節はなくても構いません . * switch 文による場合分けは , ある値と定数 ( 定数式 ) との比較しカてきません複雑な条件判 定が必要な場合は , if 文を使います .
プログラムリス 255 4.22 ス べ ・エ ・ 1 * 0 for ( : " 選択 ? switch (get_menu (mnu_main, return ー case ー 1 ー data—input ( 房 break : case ー 2 ー data—browse ( 房 break; case ー 3 ー data—undelete ( 房 break ー ー 4 ー data_save ( ) : break; " 12340 " ) ) / * データ入力 * / / * データ表示 * / / * データ復活 * / / * データセープ * /
/ 2 プ C & C + + ス円 実行例 1 メ・ニ -- コ . 1 ] ファイルをロード 2 ] ファイルをセープ 終了 選択 ? 1 ファイルをロードします 実行例 2 . ュ . 1 ] ファイルをロード 2 ] ファイルをセープ 終了 選択 ? 2 ファイルをセープします 実行例 3 メニ、 コ - 1 ] ファイルをロード 2 ] ファイルをセープ o ] 終了 選択 ? 3 プログラムを終了します 演習問題 switch 文の中の break は何か調べなさい . また , このサンプレプロクラムの中の break を取るとどうなるかテストしなさい .
ープ なっています . void run(void) for ( : 4.8 メインノレ ・データベースの実際の処理を行う run は , 次のように無限ループに 225 switch (get_menu (mnu_main, return,• C as e ー 1 ー data—input ( 房 break; case ー 2 ー data—browse ( 房 break; case ー 3 ー data—undelete ( 房 break; case ー 4 ー data_save( ) ー break; " 選択 ? " 12 3 4 0 " ) ) データ入力 * / データ表示 * / データ復活 * / データセープ * / まず get ー menu でメインメニューを表示し , 処理を選択させます . そして , ユーザーの選択により次の関数を起動します . つまり , 関数 run は , データベースの各処理関数に振り分けているだけです .
プ . / 場合分け 。ファイルをロードします Yn" 。ファイルをセープします Yn" ) : 土 n し select; char s [ 8 0 ] : main( ) #include く s し dl 土 b . h > #include く s む d 土 0 . h > サンプルプログラム 33 a し 0 土 ( s 房 " 0 ] 終了 Y n " 房 printf ( " 2 ] ファイルをセープ¥ n " 房 printf ( " 1 ] ファイルをロード Yn " 房 print f ( " メニュー Y n " 房 select gets ( s ) : printf ( printf い printf ( printf ( " switch (select) { putchar(' Yn ・ ) : case 1 : printf ( break; case 2 : printf ( break; default: printf ( return 0; ・・プログラムを終了します Yn " ) :
23 イ 4 ・データベース 関数 data-browse の主要部分を次に示します . ▽ 0 土 d data_browse (void) if (is—empty( ) ) { printf(" データ表示¥ n " 房 printf ( ” printf("** データなし **YaYnYn"),• re turn : / * データが空なら何もしない * / for pr—record ( ) : " 選択 ? " switch (get_menu (mnu_browse, return; case ー 1 ー れ 123456780 " ) ) if (next—data ( ) ) putchar い Ya ' ) : break ー case ー 2 ー / * すでに最後のレコードに達している * / case ー 8 ー data—sort ( ) : break : まだデータが未入力の場合 , この関数は意味を持たないのですぐ return し あとは , メインメニューの run と同じように無限ループになってい ています . ます . ープでは , 先頭でカレントレコードを表示し , 表示モードにおける 無限丿レ メニューを表示します . そして , ューザーが選択した項目に応じて各処理関 数を呼び出します .
4.22 フ勾グラムリスト 2 / * qsort のための比較関数 * / 土 n し s 〇 rt_fn (const void *a ′ const VOid *b) Struct Person *X y switch ( curr_item) case ー 1 ー (struct person * ) a, (struct Person *)b; strcmp (x—>name , case ー 2 ー return strcmp (x—>ruby, case ー 3 ー y—>name ) ー y->ruby); return strcmp (x—>phone , y—>phone ) : case ー 4 ー return strcmp (x—>zip_code ′ case ー 5 ー return strcmp (x—>addressl , case ー 6 ー return strcmp (x—>address2 ′ return 0 : default : y—>zip—code) ー y->addressl) : Y->address2 ) : void sort (void) qsort ( data, next_inpu に′ sizeof (struct Person) ′ sort_fn) :
・テータベース 250 4 void data sort (void) pr 土 n し f ( " データソート Yn" / * 項目番号の取得 * / " 項目番号 ? " set_item(get_menu(mnu—item, sort( ) : top—data ( ) : set—change ( ) : / * データ表示 * / void data_browse (void) if (is—empty( ) ) { printf(" データ表示 Yn " ) : printf ( " printf("** データなし **YaYnYn"); re turn ー " 123456 " ) ) : ータに変更が加えられた / * デ ータが空なら何もしない / * デ for ( : pr—record ( 房 " 選択 ? switch (get_menu (mnu browse, re turn : case ー 1 ー " 123456780 " ) ) if (next—data ( ) ) putchar い Y a ・ ) : break : case ー 2 ー / * すでに最後のレコードに達している * / if (prev—data ( ) ) putchar い Ya ' 房 break; case ー 3 ー top_data ( 房 break : case ー 4 ー last_data ( ) : break ー case ー 5 ー data—search ( ) : break : / * すでに先頭のレコードに達している * /
4.22 プログラムリス / * 項目番号取得メニュー 2 イ 7 Char *mnu item " 1 ] 名前 Y n , ・ " 2 ] ふりがな Yn " " 3 ] 電話 Y n " " 4 ] 郵便番号 Yn " " 5 ] 住所 1 Y n ・・ " 6 ] 住所 2 Y n Y n " Char *mnu__search " 1 ] 次を検索 Y n " "0] 検索終了 YnYn" int data load(void) : / * 初期設定 * / void 土 n 土し ( vo 土 d ) switch (data_load ( ) ) 0 : break; C as e 1 : pr 土 n し f ( " 新規ファイルです YnYn " ) : if (is—change ( ) ) void done(void) / * 後処理 * / void data_save(void) ー exi に ( 1 房 case 2 : break; / * 検索メニ ユ / * 関数プロトタイプ * / / * 関数プロトタイプ * / prin し f ( " データが変更されています YaYn " " セープしますか ? Y n " if (get_menu (mnu_exit. " 選ぐ ? " data—save ( 房
47 初期設定と後処理 223 初期設定と後処理 次に , main から呼ばれる io. c の 3 つの公開関数を順に見ていくことにします . Oinit この関数は , main から一番最初に呼ばれ , アプリケーション全体の初期設 定を行います . ・データベースでは , データファイルを読み込みます . これは , 同じく io. c で定義されている data-load という非公開関数を呼び出すことで処理しま す . この関数は , うまく読み込めたかどうかで , 次の値を返します . ・・読み込みに成功 ・・ファイルが見つからない ・読み込み工ラー case 文を使って , これら 3 通りについて処理を分けます . 0 の場合は , その まま break します . 1 の場合は , 新規ファイルなので , その旨を表示して break します . 2 の場合は , 工ラーが発生しているので処理を続行すると危険 です . そこで , exit(l) によりプログラムを強制終了します . 関数 init を次に示します . void 土 n 土に ( vo 土 d ) switch (data_load( ) ) case O: break; C a S e 1 : pr 土 n し f ( " 新規ファイルです Yn ¥ n " ) : break; case 2 : exi し ( 1 ) : 0 1 2