210 likes | 394 Views
第 4 週 ループ処理. プログラミング言語 2014 立命館大学情報理工学部. List 4-1 (PP.60--P.61) do-while 文 (必須知識) {} の 内部を繰り返す.条件が成立する限り. /* 入力整した数が偶数か奇数かを判断することを繰り返す */ #include < stdio.h > int main(void) { int cont ; int no; do { printf (“ 整数を入力してください ); scanf (“%d”, &no); if(no % 2)
E N D
第4週ループ処理 プログラミング言語 2014 立命館大学情報理工学部
List 4-1 (PP.60--P.61) do-while文 (必須知識){}の内部を繰り返す.条件が成立する限り /* 入力整した数が偶数か奇数かを判断することを繰り返す */ #include <stdio.h> int main(void) { intcont; int no; do { printf(“整数を入力してください); scanf(“%d”, &no); if(no % 2) puts(“その数は奇数です.”); else puts(“その数は偶数です.”); printf(“もう一度? [Yesは0, Noは9] : “); scanf(“%d”, &count); } while( count == 0 ); return 0; } { }で囲まれた部分を繰り返す ( ) 内の条件が成立する限り
実行してみよう(PP.60--61) 最初に整数として4を入力 これは2で割るとあまりが0 だから「偶数」と表示 「もう一度実行するか」と聞かれる 0を入力 0だから,もう一度実行 整数として3を入力 これは2で割るとあまりが1 だから「奇数」と表示 整数を入力してください: 4 その数は偶数です. もう一度? [Yesは0, Noは9] : 0 整数を入力してください: 3 その数は奇数です. もう一度? [Yesは0, Noは9] :
実行例を コードをたどりながら(PP.60--61) #include <stdio.h> int main(void) { intcont; int no; do { printf(“整数を入力してください); scanf(“%d”, &no); if(no % 2) puts(“その数は奇数です.”); else puts(“その数は偶数です.”); printf(“もう一度? [Yesは0, Noは9] : “); scanf(“%d”, &cont); } while( count == 0 ); return 0; } 整数を入力してください: 4 その数は偶数です. もう一度? [Yesは0, Noは9] : 0 整数を入力してください: 3 その数は奇数です. もう一度? [Yesは0, Noは9] : 条件成立だから 繰り返し
List 4-6(P.67) 初期化子,複合代入演算子,後置演算子(必須知識)ループに関連した演算 初期化子: 変数の定義時に初期値を代入 /* 1から5までの和 */ #include <stdio.h> int main(void) { int no = 1; int sum = 0; do { sum += no; no++; } while ( no <= 5); printf("1から5までを足した値は%dです.\n", sum); return 0; } 複合演算子:sum = sum + no; と同意 後置演算子:no の値を1増やす sumの初期値は0,noの初期値は1 do-whileにより, noの値をsumに加え noを1増やす これらをnoが5以下なら繰り返す
複合代入演算子 (PP.64--66 必須知識) +, -, *, /, % などの演算子に対して 変数 演算子= 式; は 変数 = 変数 演算子 式; の意味となる.評価結果は代入された値 [例] int main(void) { intnumber = 10; number += 2; /* numberの値は10 + 2 で 12 */ number *= 2; /* numberの値は 12 * 2 で 24 */ return 0; } 複合代入演算子の評価結果は上が12で下が24
後置演算子(P.67必須知識) 変数++ 変数の値をひとつ増やす 変数-- 変数の値をひとつ減らす 後置演算子では,評価してから,1だけ増やす(減らす) [例] 上の評価結果は10で, 下の評価結果は11 int main(void) { intnumber = 10; number ++; /* numberの値は10 + 1 で 11 */ number --; /* numberの値は 11 - 1 で 10 に戻る */ return 0; }
List 4-7(P.68) while文 (必須知識)条件が成立する限り内部を繰り返し ループ変数: 繰返しを制御する変数この変数の値を操作して制御 /* 0までカウント・ダウン */ #include <stdio.h> int main(void) { int no; printf("整数を入力: "); scanf("%d",&no); while( no >= 0 ) { printf("%d ", no); no--; /* デクリメント(1だけ減らす) */ } putchar('\n'); /* 改行 */ return 0; } ( ) 内の条件が成立する限り { }内を繰り返す % ./ex4-7 整数を入力: 3 3 2 1 0 % do-while() 文は,実行してから条件判定 (1度は,必ず,内部が実行される) while()文は,条件判定してから内部を実行 (1度も,内部が実行されないことがある)
文字定数とputchar() (P.69) 文字定数: 1文字を一重引用符で囲ったもの [例]‘a’, ‘X’, ‘7’, ‘*’ 改行やタブなど,見えない1文字の表現 ‘\n’ 改行, ‘\t’ タブ putchar(): 1文字を印字 [例] putchar(‘a’)・・・ 1文字aを印字 putchar(‘\n’)・・・ 改行
List 4-10(P.72) 後置演算子を用いた簡潔表現 % ./ex4-10 整数を入力: 3 *** % /* 指定された数だけ * を連続表示 */ #include <stdio.h> int main(void) { int no; printf("整数を入力: "); scanf("%d",&no); while( no-- > 0 ) putchar('*'); putchar('\n'); /* 改行 */ return 0; } 整数として3が入力される no の値は 3 条件式で no-- > 0 が成立(3 > 0 だから) noの値は2 * を1つ印字 条件式で no-- > 0 が成立(2 > 0 だから) noの値は1 * を1つ印字 条件式で no-- > 0 が成立(1 > 0 だから) noの値は0 * を1つ印字 条件式で no-- > 0 が不成立(0 > 0 だから) noの値は-1 ループを終了して改行を1つ印字 return 0; [注] 最初は以下がおすすめ while( no > 0 ) { putchar(‘*’); no--; }
List 4-11(P.73) 前置演算子変数の値を先に1つ増やしてから評価 % ./ex4-11 整数は何個?: 3 No.1: 55 No.2: 23 iの初期値は0なのに, No.1 が最初に印字されるのはなぜ? /* 指定された数だけ整数を入力し,合計と平均を計算 */ #include <stdio.h> int main(void) { inti = 0; int sum = 0; /* 合計値 */ intnum, tmp; printf("整数は何個?: "); scanf("%d",&num); while( i < num ) { printf("No.%d: ", ++i); scanf("%d", &tmp); sum += tmp; } printf("合計値: %d\n", sum); printf("平均値: %d\n", (double )sum / num); return 0; } numの値として3が入力される 条件式で i < numが成立(0 < 3 だから) このときiの値は0 No.1 と印字 (先に値が増やされるのでiの値は1だから) 条件式で i < numが成立(1 < 3 だから) このときiの値は1 No.2 と印字 (先に値が増やされるのでiの値は2だから) プログラミングでは変数の値が次々と変化する その時点でのすべての変数の値の組をプログラムの状態という
無限ループ(P.134, P.136) ループの継続条件が常に成立するループ [例] do-while文やwhile文での条件を1にしたとき int main(void) { while(1) printf(“だれか止めてよう~\n”); return 0; } もし,間違って無限ループをもつプログラムを実行してしまったら,ctrl-C(コントロール・キーを押しながらC) で止めることができる.
List 4-12(P.74--75) for文 (必須知識)ループ変数を初期化し,条件成立の限り,ループ変数を更新しながら % ./ex4-12 整数は?: 9 0 1 2 3 4 5 6 7 8 9 % /* 指定された整数までカウントアップ */ #include <stdio.h> int main(void) { inti, no; printf("整数は?: "); scanf(“%d”,&no); for( i = 0;i <= no;i++ ) { printf("%d ", i); } putchar('\n'); return 0; } ループ変数の初期化 (これは1度だけ) 繰り返しを続ける条件 繰り返しを続ける条件 成立ならforの内部を実行 成立ならforの内部を実行 条件判定→実行→更新 を繰り返す ループ変数の更新 ループ変数の更新
実行例を コードをたどりながら(PP.74--75) 今度は2とする /* 指定された整数までカウントアップ */ #include <stdio.h> int main(void) { inti, no; printf("整数は?: "); scanf(“%d”,&no); for( i = 0;i <= no;i++ ) { printf("%d ", i); } putchar('\n'); return 0; } % ./ex4-12 整数は?: 2 % 0 1 2 ループ変数を更新し, 条件が充たされる限り繰り返す
for文での注意事項(P.75) for(初期化; 繰り返し継続条件; 更新) ループ本体 • 初期化: 繰り返しが始まる前に1度だけ実行 • 初期化は,実施することがなければ,省略してもよい • 繰り返し継続条件: 評価した結果が非0なら継続 • 繰り返し継続条件を省略すると非0となり,無限ループ • 更新: 繰り返し処理の1回が終了し,次回の前に実行 • 更新は,実施することがなければ,省略してもよい
List 4-15(P.78) 多重ループ (必須知識)ループの中にループ /* 九九の表 */ #include <stdio.h> int main(void) { inti, j; for(i = 1; i <= 9; i++) { for(j = 1; j <= 9; j++) printf("%3d", i * j); putchar('\n'); } return 0; } % ./ex4-15 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81 ループが入れ子に なっている
実行例を コードをたどりながら(P.78) iを1にして, /* 九九の表 */ #include <stdio.h> int main(void) { inti, j; for(i = 1; i <= 9; i++) { for(j = 1; j <= 9; j++) printf("%3d", i * j); putchar('\n'); } return 0; } jでループを回すと1の段 iを2にして, jでループを回すと2の段 % ./ex4-15 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 内側のfor文が, 一気に実行されると考えると わかりやすい
今回押さえるべきプログラム List 4-18(P.81) 多重ループで図形 /* 直角三角形を表示 */ #include <stdio.h> int main(void) { inti, j, ln; printf("何段ですか? :"); scanf("%d", &ln); for(i= 1; i <= ln; i++) { for(j = 1; j <= i; j++) putchar('*'); putchar('\n'); } return 0; } % ./ex4-18 何段ですか? :7 * ** *** **** ***** ****** ******* % iが1のとき,星1つ iが2のとき,星2つ iが3のとき,星3つ iが4のとき,星4つ iが5のとき,星5つ iが6のとき,星6つ iが7のとき,星7つ j が i以下であるかぎり, 内側のループが回るため 星の数が行番号と一致
continueと break(P.104) (必須知識)ループの途中で実行順序を変える % ./sumOfEven 負でない整数: 6 6 8 の合計は 18 /* 負でない整数を入力し,その数から その2倍の数までの1桁の偶数の和を求める */ int main(void) { int min, max, sum; printf("負でない整数: "); scanf("%d",&min); max = 2 * min; for(sum = 0; min <= max; min++) { if(min % 2 == 1) continue; if(min >= 10) break; printf("%d ", min); sum += min; } printf("の合計は %d\n", sum); return 0; } continue は次のループ処理へ 2で割った余りが1(奇数)なら, ループ内の以下の処理をせず,次の繰り返し処理を開始 break はループを抜ける (p.105 List 5-15参照) 10以上ならループを抜ける. 多重ループなら,breakを含むもっとも内側のループを抜ける
クイズ次のプログラムの実行結果を示せ #include <stdio.h> int main(void) { intln = 5, i,j; for(i = 1; i <= ln; i++) { for(j = 1; j <= ln - i; j++) putchar(' '); for(j = 1; j <= i; j++) putchar('*'); putchar('\n'); } return 0; }
正解 * ** *** **** ***** 第1行は4つ空白,1つ星印 第2行は3つ空白,2つ星印 第3行は2つ空白,3つ星印 第4行は1つ空白,4つ星印 第5行は空白なし,5つ星印