プログラミング入門 第4回講義 選択(分岐) - if, switch/case - データ構造とアルゴリズム(2) プログラム制御の基本構造(4) 条件式(6) 多岐選択(11) switch-case(14) 良くあるミス(20) マークのあるサンプルプログラムは /home/course/prog0/public_html/2013/lec/source/ 下に置いてありますから、各自自分のディレクトリに コピーして、コンパイル・実行してみてください
データ構造 データとは問題を解くために必要な情報のこと データ構造とは データを管理する方法 のこと データ構造とは データを管理する方法 のこと データ構造は、変数の様々な型や組み合わせによって実現される 通常の変数以外に、例えばプログラミング入門では「配列」、後期プログラミングCでは「構造体」や「連結リスト」などが登場する C++,Javaなどの「オブジェクト指向言語」では「オブジェクト」とも呼ばれる 1
アルゴリズム アルゴリズムとは 問題を解く手順 のこと いろいろなアルゴリズムに関して、2年前期の「アルゴリズムとデータ構造」にて講義がある アルゴリズムとは 問題を解く手順 のこと いろいろなアルゴリズムに関して、2年前期の「アルゴリズムとデータ構造」にて講義がある アルゴリズムを表現するために、言葉やフローチャート(後述)で図示する等の方法がある データ構造を用いてアルゴリズムを実現した ものが プログラム である 2 3
プログラム制御の基本構造 連接 (これまで習った) 選択(条件判断) (今日習う) 繰り返し(ループ) (次回習う) 連接 (これまで習った) 手続き(処理、文)を上から順に実行 選択(条件判断) (今日習う) 条件の真偽で、次の手続きを選択する 繰り返し(ループ) (次回習う) 繰り返し条件が真のとき、繰り返し範囲の手続きを繰り返し実行する プログラムは、以上3つの要素の 組み合わせで出来ている! 4 5 6
選択(if文)(p.102) 選択(条件式の真偽による) if文の形(単文・複文) 条件式が真の時だけ、 文を実行 条件式が真の時だけ、 文を実行 if文の形(単文・複文) 文が複文の場合は{}で囲む 図的表現例 フローチャート(p.60) 7 偽 条件式 真 if 条件式 文 ( ; ) 文(文並び) if(score >= 50) { printf("得点は%d点でした。\n", score); printf("合格です。\n"); } 表示:“A” /home/course/prog0/public_html/2013/lec/source/lec04-1.c
条件式のポイント(p.104) 条件式の値 真 (1) または 偽 (0) を返す 条件式の構文 オペランド1 関係演算子 オペランド2 真 (1) または 偽 (0) を返す 条件式の構文 オペランド1 関係演算子 オペランド2 Cでは、0が偽、 0以外は真である。 つまり、if (0)は常に偽、 if (1), if(3)等は常に真 定数,変数,式のこと 関係演算子の使用上の注意 >= を逆に =>と、 <= を =< と書いてはいけない 関係演算子の間にスペースを入れて、< =などと書いてはいけない
条件式の拡張(p.107) 複数関係の表現 条件式の値は真または偽 真または偽を値とする演算→論理演算 条件式1 論理演算子 条件式2 条件式1 論理演算子 条件式2 8 (なお、否定論理演算子の場合は条件式1は不要)
条件式の例 if(0 <= x && x <= 100) printf(..); もし 0≦x かつ x≦100 が真ならば、条件式が1となり 表示を実行 (つまり0≦x≦100 の時printfを実行する) 注意: if(0 <= x <= 100) とは書けない!! if(y <= 0 || y >= 100) printf(..); もし y≦0 または y≧100 が真ならば、条件式が1となり 表示を実行 if( !(x == 3) ) printf(..); もし xが3でない(3以外) が真ならば、条件式が1となり 表示を実行 9
双岐選択if-else文(p.116) 双岐選択 双岐選択(if-else)の形 条件の 真偽 で文(または複文)を選択する ( ) ; ; 条件の 真偽 で文(または複文)を選択する 双岐選択(if-else)の形 例:数aの正負を判定し、aの絶対値 の2倍を求め、変数ansに代入する 10 ( 条件式 ) ; if 文1 図的表現例 フローチャート 正:2*a a > 0 真 偽 負又は0:-2*a ; else 文2 if(a>0)ans=2*a; else ans=-2*a; (文は複文も可)
双岐選択if–else文サンプル if( a > 0 ){ printf("%dは正\n",a); ans = 2 * a; } 11 ansにaの絶対値の2倍を代入 /home/course/prog0/public_html/2013/lec/source/lec04-2.c
それぞれのif-elseのペアを色分けしてある 更に、多岐選択のプログラミング 多岐条件文 いくつもの条件が重なり合った選択 「多岐条件文」の例(p.123~) if ( 信号 が 青 ) 進む; else if( 信号 が 赤 ) 止まる; else if( 信号 が 黄 ) 注意; else 信号の色の誤り; /*赤青黄以外*/ それぞれのif-elseのペアを色分けしてある
交通信号機:if~else if版(p.125) #include <stdio.h> main() { int signal; printf("0:red, 1:green, 2:yellow : "); scanf("%d",&signal); if(signal == 0) printf("Stop\n"); else if(signal == 1) printf("Go\n"); else if(signal == 2) printf("Be careful\n"); else printf("Look at the traffic signal\n"); } printf /home/course/prog0/public_html/2013/lec/source/lec04-3.c
if~else if~else文の図的表現 フローチャート 真 if(条件式1) 文1 偽 真 if(条件式1) 文1; else if(条件式2) 文2; else if(条件式3) 文3; else 文4; else if(条件式2) 文2 偽 真 else if(条件式3) 文3 偽 文4
多岐選択のもう一つの方法-switch文-(p.117) 条件式の値が、定数式で表せるときは!! case 2: switch文 が便利 case 1: case 3: case 4: switch~case 文の効果 式の値 = 3のとき、 case 3: の文を選択 case 5: その他 case 6:
switch-case文の書式 式の値と定数式の値が 等しい時、「:」に続く文を選択 switch(式){ case 定数式1: 文1; 12 switch(式){ case 定数式1: 文1; 文2; … break; case 定数式2: default: } 複数の文を書けるが、{}は必要ない! switch文から抜ける 13 どのcaseとも値が 不一致のとき選択 14 default中のbreakはなくても良い
入賞者の判別プログラム (p.118) scanf("%d",&jyuni); 変数 jyuni の値によって switch(jyuni) { case 1: printf("一位\n"); break; case 2: printf("二位\n"); case 3: printf("三位\n"); default: printf("残念\n"); } 変数 jyuni の値によって 1なら「一位」と表示 2なら「二位」と表示 3なら「三位」と表示 1,2,3位以外なら 「残念」と表示 15
switch~case文のポイント(1) 式の値は、整数(又は文字) 定数式の値は、整数(又は文字) default は、必ずcase文の最後に記述 一つのswitch-case文の中で、定数式の値が等しい複数のcase文が存在するのは誤り case 1: ... break; 16
switch~case文のポイント(2) 通常はcaseの最後に必ず break 文をつける。但し、意図して つけない場合は必ずコメントにてその旨を説明しておく 17 switch(month) { /* 以下の7つの月は同じ処理なのでbreak省略 */ case 1: case 3: case 5: case 7: case 8: case 10: case 12: printf("31日まである月\n"); break; default: printf("短い月\n"); } 「/*」と「*/」で囲まれた区間の事で、この中に記述された事はプログラムには影響しない。 コメントにはこの例のような注意点などのメモや、実行方法、作者名、日付など後で見た時にプログラムを理解し易くする事を記載する。 コメントとは? /home/course/prog0/public_html/2013/lec/source/lec04-4.c
見かけはif-else-if版より長いが、読み易い 交通信号機:switch版(p.125) #include <stdio.h> main() { int signal; printf("0:red, 1:green, 2:yellow : "); scanf("%d",&signal); switch(signal) { case 0: printf("Stop\n"); break; case 1: printf("Go\n"); case 2: printf("Be careful\n"); default: printf("Look at the traffic signal\n"); } 見かけはif-else-if版より長いが、読み易い printf /home/course/prog0/public_html/2013/lec/source/lec04-5.c
良くあるミス(if編1) {}のつけ忘れ 正しくは if (a != b) a = b; このprintfはif文の外なので、必ず実行される! if (a != b) a = b; printf("a,b were not equal\n"); 正しくは if (a != b){ a = b; printf("a,b were not equal\n"); }
良くあるミス(if編2) if文の内で条件式の後ろに「;」をつけてしまう 正しくは if (a != b); printf("a,b were not equal\n"); 条件式に;を付けると、このprintfはif文の外になり、常に実行! 正しくは if (a != b) printf("a,b were not equal\n");
良くあるミス(if編3) =と==の間違い 正しくは a = 0; b = 1; if (a = b){ printf("a,b were equal\n"); } 条件式中のaへの代入が実行され、 条件式の値はbの値(1,真)となる。 つまりa,bの値が異なるのに「a,b were equal」と表示されてしまう。 なお、これは文法ミスではないので、コンパイル時にエラーにはならない。 正しくは a = 0; b = 1; if (a == b){ printf("a,b were equal\n"); }
良くあるミス(switch編1) switch文にbreakを付け忘れる switch(a){ case 1: printf("a=1\n"); /* break つけ忘れ */ case 2: printf("a=2\n"); break; .. } aが1の時、2つとも表示される。 aが2の時は正常に動作する。
良くあるミス(switch編2) case文に書けるのは整定数(又は文字定数*)だけ switch(a){ case 5.2: printf("a>5\n"); break; case 2: printf("a=2\n"); .. } 「case label does not reduce to an integer constant」 と言うメッセージが出てコンパイルエラーになる *注:文字に関しては後期プログラミングCにて習う