Presentation is loading. Please wait.

Presentation is loading. Please wait.

プログラミング入門 第5回講義 第5回講義 制御の流れ(1) ループ(その1) - while - インデント(3) ループとは(7)

Similar presentations


Presentation on theme: "プログラミング入門 第5回講義 第5回講義 制御の流れ(1) ループ(その1) - while - インデント(3) ループとは(7)"— Presentation transcript:

1 プログラミング入門 第5回講義 第5回講義 制御の流れ(1) ループ(その1) - while - インデント(3) ループとは(7)
プログラミング入門  第5回講義 第5回講義 制御の流れ(1) ループ(その1) - while - インデント(3) ループとは(7) フローチャート(8) ループの種類・while文(10) 代入演算子(14) インクリメント・デクリメント(15) 無限ループ(20)   マークのあるサンプルプログラムは /home/course/prog0/public_html/2013/lec/source/ 下に置いてありますから、各自自分のディレクトリに コピーして、コンパイル・実行してみてください

2 復習:if/switch-caseの使い分け
変数の値による場合分けで、しかも場合が比較的多い時 (条件は等号でないといけない事に注意) いくつかの場合の処理が同じなら、breakなしのcaseが使える if文をつかう場面 条件が複雑な時(例えば、「条件AとBの真偽による4つの場合分け」にはswitch-caseを使用する事は非常に難しいだろう) 条件が等号でない場合(!=、<、<=、>、>=など) switch-caseが使える時でも、あまり場合分けが多くない(3個ぐらい)だとif-elseを使用した方がコンパクトにまとめられる

3 自動的にインデントする方法は、Lec06-15で説明します
インデント(段づけ)をしよう! インデント(段づけ)をすると 見やすく、間違いにくく なる 以下のスタイル1、2が標準的。 スタイル1(行数が少なく、コンパクトにまとまる) if (a == b){ printf("a,b were equal\n"); } 自動的にインデントする方法は、Lec06-15で説明します スタイル2(カッコの対応が見易い) if (a == b) { printf("a,b were equal\n"); }

4 複雑なif文に騙されるな(1) 以下は日付を入力して、それが月の最後の日かどうかを表示するプログラム。(ただし閏年と、あり得ない日付(5月40日など)には対応していない) #include <stdio.h> main() { int m,d; printf("月と日を空白で区切って入力してください : "); scanf("%d %d",&m, &d); if((m == 1) || (m == 3) || (m == 5) || (m == 7) || (m == 8) || (m == 10) || (m == 12)) if(d == 31) printf(“%d月%d日は月の最後の日\n",m,d); else if((m == 4) || (m == 6) || (m == 9) || (m == 11)) if(d == 30) printf("%d月%d日は月の最後の日\n",m,d); else if(m == 2) if(d == 28) printf("%d月%d日は月の最後の日\n",m,d); else printf("%d月%d日は月の最後の日ではない\n",m,d); } みかけは正しそうだが、実際はうまく動かない /home/course/prog0/public_html/2013/lec/source/lec05-1.c

5 複雑なif文に騙されるな(2) 前頁のプログラムをちゃんとインデント(if-elseの関係に注目して段づけする)してみると、以下のようになり、論理的におかしい事が分かる。 #include <stdio.h> main() { int m,d; printf("月と日を空白で区切って入力してください : "); scanf("%d %d",&m, &d); if((m == 1) || (m == 3) || (m == 5) || (m == 7) || (m == 8) || (m == 10) || (m == 12)) if(d == 31) printf("%d月%d日は月の最後の日\n",m,d); else if((m == 4) || (m == 6) || (m == 9) || (m == 11)) if(d == 30) printf("%d月%d日は月の最後の日\n",m,d); else if(m == 2) if(d == 28) printf("%d月%d日は月の最後の日\n",m,d); else printf(“%d月%d日は月の最後の日ではない\n",m,d); } /home/course/prog0/public_html/2013/lec/source/lec05-2.c

6 複雑なif文に騙されるな(3) これが正しいプログラム(インデントも正しくされている) #include <stdio.h>
main() { int m,d; printf("月と日を空白で区切って入力してください : "); scanf("%d %d",&m, &d); if(((m == 1) || (m == 3) || (m == 5) || (m == 7) || (m == 8) || (m == 10) || (m == 12))&&(d == 31)) printf("%d月%d日は月の最後の日\n",m,d); else if(((m == 4) || (m == 6) || (m == 9) || (m == 11))&&(d == 30)) else if((m == 2)&&(d == 28)) printf("%d月%d日は月の最後の日\n",m,d); else printf("%d月%d日は月の最後の日ではない\n",m,d); } lec05-3c.cは更に閏年にも対応した /home/course/prog0/public_html/2013/lec/source/lec05-3{a,b,c}.c

7 繰り返し(ループ)とは何か(p.132) ある条件が成立している間、 同じ処理を何度も繰り返すこと Cの繰り返しの命令(文)
お金がある限り宝くじを買う グラウンドを20周する Cの繰り返しの命令(文) while, for, (do-while)

8 フローチャート(p.60) 前回既に登場 下のような図形を有向線でつないで処理の手順(アルゴリズム)を表す 処理 起点・終点 入出力 分岐
ループ開始 ループ終了 キー入力 真の場合の処理 条件分岐 偽の場合の処理 画面出力

9 繰り返しのフローチャート 九九の七の段の計算 yに7を代入 繰り返し: xを1から9まで1ずつ増加 zにx*yの計算結果を代入 zの値を表示
図的表現例 九九の七の段の計算 yに7を代入 繰り返し: xを1から9まで1ずつ増加    zにx*yの計算結果を代入    zの値を表示 繰り返しここまで フローチャート xを1から9まで1ずつ増加 z=x*y; zを表示

10 ループの種類(p.132) 見張り方式(while) 今回とりあげます カウンタ方式(for) 次回とりあげます
ある特定の条件を満たしている間は、処理を 繰り返す(例:aが0より大きい間) 一般に繰り返し回数は あらかじめ決まっていない カウンタ方式(for)  次回とりあげます ループの回数を数える変数(カウンタ変数などと呼ぶ)を用いて繰り返し処理を決定する(例:10回) 一般的に繰り返し回数は 固定

11 while 文(見張り方式に良く使われる)(p.132)
条件式が真の間はループの中身を実行し続け、条件式が偽になれば終了(ループの次の文を実行)する while(条件式){ 文; ... }

12 ループのサンプルプログラム A B #include <stdio.h> main() { int i,total;
 ループのサンプルプログラム 1+2+3....と順に加えていって、初めて和が25を超える数と、その時の和を求める #include <stdio.h> main() { int i,total; i = 0; total = 0; while( total <= 25 ){ i = i + 1; total = total + i; } printf("数は %d で、和は %d です\n", i, total); std1dc1{s }1: gcc lec05-7.c std1dc1{s }2: ./a.out 数は 7 で、和は 28 です std1dc1{s }3: A B /home/course/prog0/public_html/2013/lec/source/lec05-4.c

13 実行経過 値 ループ A地点 B地点 i total 1回目 1 2回目 2 3 3回目 6 4回目 4 10 5回目 5 15 6回目
値     ループ A地点 B地点 i total 1回目 1 2回目 2 3 3回目 6 4回目 4 10 5回目 5 15 6回目 21 7回目 7 28 8回目 ループから脱出(ループは7回まわった) 6 7

14 代入演算子について(p.87) =以外に, +=, -=, *=, /=, %=がある x += y ⇒ x = x + y

15 インクリメント・デクリメント演算子 (p.135)
ループの中で、カウンタ変数を使う例が多い。 繰り返し回数の把握、回数に応じた制御。 変数に1を加える操作   インクリメント i++, ++i 変数から1減じる操作   デクリメント i--, --i 符号の位置が、前(前置)と後(後置)で 意味が違う → 次ページ

16 前置と後置の違い(p.136) 前置(++i、--i) ⇒ iに1加え(減じ)てから、 値を返す
単独で使用する場合は前置でも後置でも同じ i = i + 1; j = i; と同じ 8 9 例:i=6の時、実行後の値は j = ++i; ⇒ i:7 , j:7 j = i++; ⇒ i:7 , j:6 j = i; i = i + 1; と同じ 前置 後置 例:i=6の時、実行後の値は ++i; ⇒ i:7 i++; ⇒ i:7 前置 後置

17 インクリメント・デクリメント 前置と後置の違い
#include <stdio.h> main() { int i, j; i = 0; j = 0; while( i < 5 ) { j = ++i; printf( "前置: i は %d, j は %d です\n", i, j ); } j = i++; printf( "後置: i は %d, j は %d です\n", i, j ); 2つの整数i, jは 最初0に初期化 前置の値をjに代入 今度は後置の値をjに代入。 /home/course/prog0/public_html/2013/lec/source/lec05-5.c

18 前のプログラムの出力結果 一見似たようなループなのだが、左にあるように出力結果が異なる。 前置: i は 1, j は 1 です
前置・後置を組み合わせて使う場合、この点に注意する。 前置: i は 1, j は 1 です 前置: i は 2, j は 2 です 前置: i は 3, j は 3 です 前置: i は 4, j は 4 です 前置: i は 5, j は 5 です 後置: i は 1, j は 0 です 後置: i は 2, j は 1 です 後置: i は 3, j は 2 です 後置: i は 4, j は 3 です 後置: i は 5, j は 4 です

19 インクリメント演算子・代入演算子の使用例
 インクリメント演算子・代入演算子の使用例 #include <stdio.h> main() { int i,total; i = 0; total = 0; while( total <= 25 ){ i++; total += i; } printf("数は %d で、和は %d です\n", i, total); Lec05-12のプログラムlec05-4.cを書き換えた この場合は前置でも後置でも構わない /home/course/prog0/public_html/2013/lec/source/lec05-6.c

20 whileを使った無限ループ while(1)で制御される構造は、 条件式が常に真(1)なので無限ループである。
ある条件を満たした時にループを脱出するよう、 if文でbreakを入れる使い方がある。 (入力制限・エラー処理などを、while(1){ … }でくくる) 10 while( 1 ){ printf("\n0から100までの整数を入力しなさい\n"); scanf("%d", &a); if (a >= 0 && a <= 100) break; } breakについて 第3回講義で出て来た caseからの脱出と同様、ループからの脱出にも使われる 詳しい説明は次回(第6回)講義で行う

21 無限ループの例(Lec05-12を改変) #include <stdio.h> main() { int i,total;
while(1){ if (total > 25) break; i = i + 1; total = total + i; } printf("数は %d で、和は %d です\n", i, total); 元は「和が25以下だったらループ 『継続』 」という条件だったので,   while(total <= 25) としていた。 今度は『終了』条件なので条件式が逆になっている。 和が25を越えたら無限ループを脱出する。 無限ループ 11 /home/course/prog0/public_html/2013/lec/source/lec05-7.c

22 ループとifの組み合わせ例 ある地点から別の地点へ徒歩で行く場合の所要時間を考えるプログラム 途中に信号が5カ所あるとする
信号間の所要時間は3分 信号が赤だったら信号待ちでさらに1分(計4分) 信号が青か赤かを入力して、所要時間を積算する 最後に積算結果を表示する 右の実行例では、青が3回、赤が2回 所要時間は3+3+4+4+3=17分 std1dc1{s }1: ./a.out 1番目の信号は(青:0, 赤:1)?:0 2番目の信号は(青:0, 赤:1)?:0 3番目の信号は(青:0, 赤:1)?:1 4番目の信号は(青:0, 赤:1)?:1 5番目の信号は(青:0, 赤:1)?:0 所要時間は17分でした

23 ループとifを使用したサンプルプログラム
#include <stdio.h> main () { int i = 1; int signal; int time = 0; while (i <= 5) { printf("%d番目の信号は(青:0, 赤:1)?:", i); scanf("%d", &signal); if (signal == 0) time += 3; else time += 4; i++; } printf("所要時間は%d分でした\n", time); 信号の回数(カウンタ) 信号の状態 所要時間 の3つが必要な変数 信号の回数を監視 信号の状態に応じて所要時間を加算(代入演算子を使っている) 12 信号の回数を加算 /home/course/prog0/public_html/2013/lec/source/lec05-8.c

24 ループとswitch-caseの組み合わせ例
先の例に信号が点滅していた場合を追加 点滅していたら急ぎ足になるので2分で行けるとする 危ないので実際には走らないこと 3通りになるのでswitch-caseを用いる 前ページプログラムのwhileの中だけ右に示す i = 1; while (i <= 5) { printf("%d番目の信号は(青:0, 赤:1, 点滅:2)?: ", i); scanf("%d", &signal); switch (signal) { case 0: time += 3; break; case 1: time += 4; case 2: time += 2; } i++; 実行例 std1dc1{s }1: ./a.out 1番目の信号は(青:0, 赤:1, 点滅:2)?:0 2番目の信号は(青:0, 赤:1, 点滅:2)?:0 3番目の信号は(青:0, 赤:1, 点滅:2)?:2 4番目の信号は(青:0, 赤:1, 点滅:2)?:1 5番目の信号は(青:0, 赤:1, 点滅:2)?:0 所要時間は15分でした /home/course/prog0/public_html/2013/lec/source/lec05-9.c


Download ppt "プログラミング入門 第5回講義 第5回講義 制御の流れ(1) ループ(その1) - while - インデント(3) ループとは(7)"

Similar presentations


Ads by Google