コンピュータープログラミング (C言語)(6) 1.条件分岐2(switch文、復習) 2.繰り返し処理(for文、while文) コンピュータ基礎実験 第8回 コンピュータープログラミング (C言語)(6) 1.条件分岐2(switch文、復習) 2.繰り返し処理(for文、while文)
条件分岐2(復習、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 (省略することも可能)
前回発展課題EX7-6: 知りたい年月日がその年の元日(これを第1日目とする)から数えて何日目で,大晦日まで何日残っているかを計算するプログラムを作成せよ.ただし,考えている年がうるう年であるか,そうでないかにより計算を区別するものとする..( EX7-6.c )
前回発展課題EX7-6その1:EX7-6.c 「m2+=ly;」⇔「m2=m2+ly;」 #include <stdio.h> int leapyear(int year); int main(void) { int year, month, day; int days, rest; int ly; int m1=31, m2=59, m3=90, m4=120, m5=151, m6=181; int m7=212, m8=243, m9=273, m10=304, m11=334, m12=365; printf("西暦 月 日を入力: "); scanf("%d %d %d", &year, &month, &day); ly=ileapyear(year); m2+=ly; m3+=ly; m4+=ly; m5+=ly; m6+=ly; m7+=ly; m8+=ly; m9+=ly; m10+=ly; m11+=ly; m12+=ly; switch(month){ case 1: days=day; rest=m12-days; break; case 2: days=m1+day; rest=m12-days; case 3: days=m2+day; rest=m12-days; case 4: days=m3+day; rest=m12-days; case 5: days=m4+day; rest=m12-days; case 6: days=m5+day; rest=m12-days; case 7: days=m6+day; rest=m12-days; case 8: days=m7+day; rest=m12-days; case 9: days=m8+day; rest=m12-days; case 10: days=m9+day; rest=m12-days; case 11: days=m10+day; rest=m12-days; case 12: days=m11+day; rest=m12-days; } printf(“%d日目です。あと%d日残っています。\n",days,rest); return 0; 「m2+=ly;」⇔「m2=m2+ly;」
前回発展課題EX7-6その2:EX7-6-1.c #include <stdio.h> int leapyear(int year) { /* うるう年なら1、そうでなければ0を返す */ int m1,m2,m3; m1=year%400; /* 0なら400で割りきれる */ m2=year%4; /* 0なら4で割りきれる */ m3=year%100; /* 0なら100で割りきれる */ if(m1==0 || (m2==0 && m3!==0)){ printf(“うるう年です\n"); return 1; } else{ printf("うるう年ではありません\n"); return 0;
前回発展課題EX7-6:EX7-6.c改良版 #include <stdio.h> int od(int y, int a, int b); int ly(int y); int main(void) { int a,b,c,y; printf("Input year, month and date: "); scanf("%d %d %d",&y,&a,&b); if(0>(c=od(y,a,b))) return 1; printf(“The %dth day of the year %d!\n”,c,y); printf(”%d days are left over.\n",365+ly(y)-c); return 0; } int ly(int y) if(y%400==0 || (y%4==0 && y%100!=0)){ return 1; int od(int y, int a, int b) { int c,d; c=ly(y); switch(a){ case 1: if(b>31)b=-1; c=0; break; case 2: if(b>28)b=-1; c=31; break; case 3: if(b>31)b=-1; c+=59; break; case 4: if(b>30)b=-1; c+=90; break; case 5: if(b>31)b=-1; c+=120; break; case 6: if(b>30)b=-1; c+=151; break; case 7: if(b>31)b=-1; c+=181; break; case 8: if(b>31)b=-1; c+=212; break; case 9: if(b>30)b=-1; c+=243; break; case 10: if(b>31)b=-1; c+=273; break; case 11: if(b>30)b=-1; c+=304; break; case 12: if(b>31)b=-1; c+=334; break; default: printf("Month is out of range.\n");return -1; } if(b<=0){printf("Date is out of range.\n");return -2;} return c+b;
繰り返し処理 コンピュータでは、少しずつ条件を変えながら同じ処理を繰り返す状況がよくでてきます。 前回「電卓プログラム2」でも、別の計算を続けてやりたいとき、いちいちプログラムを起動するのは面倒です。 C言語では、繰り返し処理を行うために「for文」、「while文」が用意されています。 「繰り返し」は「ループ」とも呼ばれます
繰り返し1:「for」 ある初期値を与え、それがある条件を満たしている間、同じ処理を繰り返すには、「for文」を用います。 変数に初期値を与え、条件を満たしている場合には「文」を実行する。 「文」を実行した後、「ループの終わりに実行する式」を実行し、条件を 満たしているか→「文」の実行を繰り返す。
例題1:EX8-1 (EX8-1.c) ■ for文〜ある操作を,指定した回数だけ繰り返すコマンド 例題9-1: つぎのプログラムを実行せよ. /* EX8-1.c */ #include <stdio.h> int main (void) { int i; for(i=1; i<=10; i++){ printf(" A B C \n"); } return 0; 変数iの値を1増やして i=1からi=10まで実行 [実行例] 「i++;」⇔「i=i+1;」(インクリメント) 表示したい文字列 基本構造 for(式1; 式2; 式3) 繰り返す文 式1は,繰り返し操作の初期値 式2は,条件式で,これを満たせば 繰り返しの操作を実行する 式3は繰り返しの回数を制御
例題2:EX8-2a, EX8-2b 「for文」の入れ子 課題8-2: つぎのプログラムを実行し,結果を比較せよ. 課題8-2: つぎのプログラムを実行し,結果を比較せよ. /* EX8-2a.c */ #include <stdio.h> int main (void) { int i,j; for(i=1;i<=10;i++){ for(j=1; j<=10;j++){ printf(”AB "); } printf(" \n"); return 0; /* EX8-2b.c */ #include <stdio.h> int main (void) { int i,j; for(i=1;i<=10;i++){ for(j=1; j<=i; j++){ printf("AB "); } printf(" \n"); return 0;
■ for文の基本構造 for(式1; 式2; 式3){ 繰り返す文1; 繰り返す文2; ………… ; } 例題EX8-3: 整数 nを入力し,1からnまでの 和を計算するプログラムの例. EX8-3.c for(式1; 式2; 式3){ 繰り返す文1; 繰り返す文2; ………… ; } /* EX8-3.c */ #include <stdio.h> int main (void) { int i,n,wa; printf("1からnまでの和?--> nを入力して下さい.\n"); scanf("%d",&n); wa=0; for(i=1; i<=n; i++){ wa=wa+i; } printf(" 和は %d です. \n", wa); return 0; 式1は,繰り返し操作の初期値 式2は,条件式で,これを満たせば 繰り返しの操作を実行する 式3は繰り返しの回数を制御
配列 「繰り返し処理」とともに用いると、非常に便利な機能が「配列」という機能です。 「配列」は、ベクトルや行列の成分のように、複数の数字の組み合わせを「添え字」を用いて表す「変数」(数字を記録する箱)のセットです。 a[0]、a[1]、a[2]…のようにカギ括弧を使う。添え字は0から b[0][0]、b[0][1]…: 添え字が2変数 C[0][0][0]、c[0][0][1]…:添え字が3変数
例題EX8-4「for文」と配列:EX8-4.c 前回課題「何日めかプログラム」の改訂版(EX7-6.c ,EX7-6-1.c) #include <stdio.h> intileapyear(int year); int main(void) { int year, month, day; int days, rest; int ly, i; int m[13]={0,31,59,90,120,151,181,212,243,273,304,334,365}; printf("西暦 月 日を入力: "); scanf("%d %d %d", &year, &month, &day); ly=is_leap_year(year); for(i=2; i<=12; i++){ m[i]+=ly; } days=m[month-1]+day; rest=m[12]-days; printf("%d日目です。あと%d日残っています\n",days,rest); return 0; #include <stdio.h> int leapyear(int year) { /* うるう年なら1、そうでなければ0を返す */ int m1,m2,m3; m1=year%400; /* 0なら400で割りきれる */ m2=year%4; /* 0なら4で割りきれる */ m3=year%100; /* 0なら100で割りきれる */ if(m1==0 || (m2==0 && m3!=0)){ printf(“うるう年です\n"); return 1; } else{ printf("うるう年ではありません\n"); return 0; 要素数13 m[12] m[0] 繰り返し「for文」 短くなった!
課題EX8-5: n項目までの奇数の和1+3+5+7…は に等しい。 n項目までの奇数の和を計算するプログラムを「for文」を用いて作成し、n=1, 10, 50, 100の場合についてこのことを確認せよ。 ( EX8-5.c) 課題EX8-6:自然対数の底e(=2.71828…)は次の無限級数で与えられる。 上の無限級数の初めのn項目までを計算するプログラムを作成せよ。このとき、小数点以下10桁(”%.10f”)で出力せよ。 (→ EX8-6.c) WEB上でeの値を調べ、n=1, 5, 10, 20について自分のプログラムで計算し、収束する様子を確認せよ。(double変数を使用せよ) 注)「0!=」1です。
繰り返し2:「while」 特に初期を与えずに、ある与えられた条件を満たしている間、同じ処理を繰り返すには、「while文」を用います。 「while文」は第一回目の処理を「必ず行うか」または「行わない場合もある」かで、「while文」と「do ~ while文」の2種があります。
■ do 〜 while 文 ■ while 文 while (式){ 文 } do{ 文 } while (式); 式が 「真」であるあいだ,文 を繰り返し実行する. (文を実行する前に式を評価するので 初めに式が「偽」であれば1回も実行されない) ■ do 〜 while 文 do{ 文 } while (式); 式が 「真」であるあいだ,文 を繰り返し実行する. (文を実行した後で式を評価するので 初めに式が「偽」でも必ず1回は 実行される)お尻の「;」を忘れるな!
例題EX8-7: 電卓プログラム1(EX7-2.c)の改造(while文) 2実数a, bを入力し、その後、1-4の整数を入力し、1なら和、2なら差、3なら積、4なら商を表示し、その後1を入力すればもう一度、それ以外では終了するするプログラムを作れ( EX8-7.c ) #include <stdio.h> int main(void) { float a,b; int c, d=1; while(d==1){ 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"); } printf(”もう一度->1、終了->1以外: ”); scanf(”%d”, &d); return 0;
例題EX8-8: 電卓プログラム2(EX7-3.c)の改造(do~while文) 「12.3 + 45.6」の様に数学の表記を入力すると、表記に応じて和、差、積、商を何度でも計算するプログラムを作れ。数字と演算子の間はスペースで区切るとし、演算子としては「+」「-」「*」「/」の4つがあり、演算子の部分に「s」が入力されると計算せずに終了するとする。( EX8-8.c ) #include <stdio.h> int main(void) { float a,b; char c; do{ printf("計算式を入力(例 123.5 + 43.21): "); scanf("%f %c %f",&a,&c,&b); switch(c){ case '+': printf("%f\n",a+b); break; case '-': printf("%f\n",a-b); case '*': printf("%f\n",a*b); case '/': printf("%f\n",a/b); case 's': default: printf("入力が間違っています\n"); } }while(c != 's'); return 0;
■ 「for文」 と 「while文」 の関係 式1; for (式1; 式2; 式3){ while (式2){ 文 文 } 式3; } 条件判断 初期 再初期化 for (式1; 式2; 式3){ 文 } 式1; while (式2){ 文 式3; }
課題EX8-9: 整数 nを入力し,n項目までの奇数の和を計算するプログラム(EX8-5.cではforを使って書いた)を,whileを使って書き直せ. ( EX8-9.c ) 発展課題EX8-10: キーボードから入力された、複数の正の実数について最大値と最小値を求めるプログラムを作成せよ. ただし,データに0が入ったら入力を終了するものとする. ( EX8-10.c )
実習結果のレポート 3つのソースファイル「EX8-5.c」、「EX8-6.c」、「EX8-9.c」を添付ファイルにしてメールを送ってください。 宛先: muroo@cc.tuat.ac.jp 件名:コンピューター基礎実験8 本文:感想および一言