コンピュータープログラミング (C言語)(5) 1.条件分岐1(if文、復習) 2.条件分岐2(switch,case文) コンピュータ基礎実験 第7回 コンピュータープログラミング (C言語)(5) 1.条件分岐1(if文、復習) 2.条件分岐2(switch,case文)
条件分岐1(if文、復習) キーボードからの入力や、計算結果に応じて処理内容を変える場合があります C言語では、「2重分岐」と「多重分岐」の2種類が用意されています 2重分岐: 「if文」⇒2股に分かれる 多重分岐:「switch~case文」⇒3股以上に分かれる
判断と分岐 ■ 2重分岐 …条件式により2分岐選択制御 [ if 〜 else] if 文 if (条件式) 文1; else 条件式 文1; else 文2; 条件式 (1)関係演算 … 2つの値の大小関係の比較 (2) 論理演算 … 条件を満たすか否かを判定
■ 1.関係係演算子 数学記号 C言語 = == > < ≧ >= ≦ <= ≠ != 条件式の書き方 意味 数学記号 C言語 等しい = == より大きい > より小さい < 等しいか, ≧ >= ≦ <= 等しくない ≠ != 条件式の書き方 (Ex.1) a+b = c a+b == c (Ex.2) a+b ≧c a+b >= c
■ 2.論理演算子 A, B のそれぞれを条件式として 意味 名前 C言語での表現 A && B A || B !A 論理積 AND A && B A, Bのどちらかが成立すれば 真 論理和 OR A || B Aが成立しなければれば 真 否定 NOT !A (Ex.1) “x+y = c” と “z > 0” の両方が成立すれば真 x+y == c && z > 0 (Ex.2) “0 < x < 100 ” 0 < x && x < 100 (Ex.3) “x = y = 1” x == 1 && y == 1 (注) || よりも && の方が優先順位は高い. 同じ順位の間では左から順 に評価される.また,( ) でくくってあればその中が先に評価される.
「if文」の書き方(コツ) If文は、カッコが多いので、先にカッコを書いてしまうのがコツです。 後から( )内に条件式、{ }内に文を書きます。 if(){ } else{ カッコ類は左の例のようにそろえると 見やすいです(他のスタイルもあります) if(x>=0){ printf(”|x|=%f\n”,x); } else{ printf(”|x|=%f\n”,-x); ( )内に条件式: x>=0 初めの{ }内に文1: printf(”|x|=%f\n”,x); 次の{ }内に文2: printf(”|x|=%f\n”,-x); Eclipseでは自動的に 補ってくれます 頭をそろえる(インデント)
二次方程式 ax2+bx+c=0 の解を具体的に出力するプログラムを 作れ.ただし 解が重解なら 重解 x = … 前回課題EX6-4: 二次方程式 ax2+bx+c=0 の解を具体的に出力するプログラムを 作れ.ただし 解が重解なら 重解 x = … 解が2つの実解なら 相異なる実数解 x =…, … 解が複素数なら 相異なる複素数解 x = … + … i x = … - … i のように表現せよ.( EX6-4.c) 実行例として (1) a=1, b=1, c=-2, (2) a=1, b=-2, c=1, (3) a=1,b=1, c=1 を試みよ. (注) 平方根の計算が必要になるので #include<stdio.h> のつぎに #include<math.h> を書き加えること
前回課題6-4の条件わけ 2次方程式は判別式「d=b*b-4*a*c」で解が分類されます 「dが0か?」と「dが正か負か?」の2段階で条件わけしてみます。 D=0? No 一段階目 D>0? No Yes 二段階目 Yes 重解 2実解 2複素解
枠の準備 二段階の枠を先に準備して、それから条件を入力します(インデントはEclipseが自動的に行います) if( d==0){ 重解の時の文; } else{ if( d>0 ){ 2実解の時の文; 2複素解の時の文; if( ){ } else{
フローチャートとソース フローチャートとプログラムソースは一対一に対応しています if( d==0){ 重解の時の文; } else{ 2実解の時の文; 2複素解の時の文; D=0? 重解 D>0? 2実解 2複素解 一段階目 二段階目 Yes No
複素解の表し方 複素解のとき、どうやって複素数を表せばいいでしょう? 解の公式による実部と虚部 複素数:「実部」と「虚部」 「実部」+「虚部」 i 解の公式による実部と虚部 実部:e=-b/2/a、虚部:f=sqrt(4*a*c-b*b) 「printf(”%f + %f i”,e,f);」 「printf(”%f - %f i”,e,f);」
前回課題6-4解答例 EX6-4.c EX6-4.c: #include <stdio.h> #include <math.h> int main(void) { float a,b,c,d; printf("2次方程式の係数a, b, cをいれてください(ax^2+bx+c=0): "); scanf("%f %f %f",&a,&b,&c); d=b*b-4*a*c; if(d==0){ printf("重解:\n x=%f\n",-b/2/a); } else{ if(d>0){ printf("相異なる実数解:\n x=%f, %f\n",(-b+sqrt(d))/2/a,(-b-sqrt(d))/2/a); printf("相異なる複素数解:\n x=%f+%fi, %f-%fi\n",-b/2/a,sqrt(-d)/2/a,-b/2/a,sqrt(-d)/2/a); return 0;
条件分岐2(switch、case文) 多重分岐(3重以上)には、switch、case文を使います 多重分岐は、2重分岐の多段化(例:2次方程式の解EX6-4.c)でも可能ですが、見づらく、switch、case文のほうが見やすくなる場合があります。 どちらを使っても結果は同じです。見やすい(慣れている)方を使ってください。
switch、case文 switch 文 switch (式){ case 定数1: 文1; break; case 定数2: 文2; break; ………….. default: 文; } 式の値が 定数1と等しければ 文1を実行 定数2と等しければ 文2を実行 ……. それ以外なら 文 を実行 (注) 1.case 1 など のあとにコロン(:)が必要. 2.breakに出会うとswitch{}から抜ける.breakがないとそれ以下の文を実行する. 3.どれとも一致しなければdefault (省略することも可能)
switch 文 switch (式){ case 定数1: 文1; break; case 定数2: /* ex. 7-1 */ #include <stdio.h> int main(void) { int n; printf("曜日の番号 (1…7) を入力してください:"); scanf("%d", &n); printf("この日は何曜日?: "); switch(n){ case 1: printf(" 月曜日 \n"); break; case 2: printf(" 火曜日 \n"); case 3: printf(" 水曜日 \n"); ----- (中略) ----- case 7: printf(" 日曜日 \n"); default: printf("入力番号が正しくありません. \n"); } switch 文 switch (式){ case 定数1: 文1; break; case 定数2: 文2; break; ………….. default: 文; }
注意! (注) switch 文は 文字(char型) でも受けられる /* ex. 7-1a */ #include <stdio.h> int main(void) { char x; printf(“曜日の記号 (a…g) を入力してください:"); scanf("%c", &x); printf("この日は何曜日?: "); switch(x){ case 'a': printf(" 月曜日 \n"); break; case 'b': printf(" 火曜日 \n"); case 'c': printf(" 水曜日 \n"); ----- (中略) ----- case 'g': printf(" 日曜日 \n"); default: printf("入力記号が正しくありません. \n"); } (注) switch 文は 文字(char型) でも受けられる 注意!
switch (式){ case 定数1: case 定数2: /* ex. 7-1b */ #include <stdio.h> int main(void) { int n; printf("曜日の番号 (0=日,1=月,2=火,…,6=土) を入力してください:"); scanf("%d", &n); printf("この日は何曜日?: "); switch(n){ case 1: case 2: case 3: case 4: case 5: printf(" 平日です. \n"); break; case 6: case 0: printf(" 週末です. \n"); default: printf("入力番号が正しくありません.\n"); } return 0; (注) switch 文では 複数のcase句 をまとめることも できる switch (式){ case 定数1: case 定数2: 文1; break; case 定数3: 文3; break; ………….. default: 文; }
例題EX7-2: 電卓プログラム1 2実数a, bを入力し、その後、1-4の整数を入力し、1なら和、2なら差、3なら積、4なら商を計算するプログラムを作れ( EX7-2.c ) #include <stdio.h> int main(void) { float a,b; int c; printf("2つの実数a, bを入力してください: "); scanf("%f %f",&a,&b); printf(" a=%f, b=%f\n",a,b); printf(“計算の種類(1:和、2:差、3:積、4:商): "); scanf("%d",&c); switch(c){ case 1: printf("%f+%f=%f\n",a,b,a+b); break; case 2: printf("%f-%f=%f\n",a,b,a-b); case 3: printf("%f*%f=%f\n",a,b,a*b); case 4: printf("%f/%f=%f\n",a,b,a/b); default: printf("入力が間違っています\n"); } return 0;
課題EX7-3: 電卓プログラム2 「12.3 + 45.6」と入力すると、和、差、積、商を計算するプログラムを作れ。数字と演算子の間はスペースで区切るとし、演算子としては「+」「-」「*」「/」の4つがあるとする。( EX7-3.c ) 「演算子を表す文字」はchar型変数に記録することができる 「1 + 2 」 なら scanf(”%f %c %f”,&a,&b,&c); (a,c: float型、b: char型) 「b」には「+」という文字が代入されている 「switch, case」文中では文字は「’」(クオート)で囲むことをわすれるな
課題EX7-4: 今年の月と日を入力し、それが今年の1月1日から数えて何日目かを求めるプログラムを作成せよ. ただし、うるう年は考えないとする。( EX7-4.c ) ヒント: 前月までの月の合計数に日を加えればよい. (5月29日なら1月~4月の日の合計(31+28+31+30)に29を 加えればよい) 課題EX7-5: 今年の1月1日は日曜日でした.今年の月と日を入力し,それが何曜日であるかを出力するプログラムを作成せよ. ( EX7-5.c ) ヒント:1月1日から数えて何日目かを7で割ったあまりを利用 1月1日(1日目)が木曜なら、1月2日(2日目)は何曜日?
発展課題EX7-6: 知りたい年月日がその年の元日(これを第1日目とする)から数えて何日目で,大晦日まで何日残っているかを計算するプログラムを作成せよ.ただし,考えている年がうるう年であるか,そうでないかにより計算を区別するものとする..( EX7-6.c )
実習結果のレポート 3つのソースファイル「EX7-3.c」、「EX7-4.c」、「EX7-5.c」の中から少なくとも一つを添付ファイルにしてメールを送ってください。(もちろん3つとも提出してかまいません。) 宛先: muroo@cc.tuat.ac.jp 件名:コンピューター基礎実験7 本文:感想および一言