プログラミング入門 II 2009年後期
プログラミング入門 II 担 当 教 員 : 上村 技術スタッフ: 月川、北本、細島 ティーチング・アシスタント(TA): 島田、鈴木、高野、根岸、林原 前澤、山下、山中、若林 レポート:必須2回、任意2回の計4回 コースナビ: C言語入門編 達成度60%以上 出席: 2/3以上 20分以内の遅刻は0.5回 20分以上の遅刻は入室は認めるが、出席は0 100%なら任意レポート満点 10回以上
単位修得の要件: 2/3以上の出席 必須レポートの提出 コースナビ(e-learning)のC言語入門編 60%以上 「期末試験 + レポート」の60%以上 10回以上 2回 注意! レポートのファイルは保存しておくこと 成績評価法: 上記要件を満足した者について 期末試験80点+レポート合計20点=100点満点 のうち 90点以上:秀、80点以上:優、70点以上:良、60点以上:可
講義予定(前半): 回 月 日 内 容 (予定) レポート 1 10月2日 講義の概要・コースナビの説明 月 日 内 容 (予定) レポート 1 10月2日 講義の概要・コースナビの説明 第17章 その他の制御文・第18章 マクロ 2 10月9日 第11章 関数について オーバーヘッド、大域変数 3 10月16日 第10章 関数 10.9 関数と配列の演習 第1回レポート(必須) 第12章 関数と配列 (10/24提出) 4 10月23日 第13章 文字の取り扱い方 文字、文字列、文字型配列、問題13.3,13.5 5 10月30日 第15章 文字列処理 文字列処理用ライブラリ関数、問題15.1 6 11月13日 第14章 ファイル操作 第2回レポート(任意) 問題14.1,14.5 (11/14提出) 7 11月20日 第16章 構造体 定義、構造体関数 8 11月27日 演習、ゲーム作成
講義予定(後半): 各自のコースナビ「C言語入門編」の進度を毎週、発表予定。 積極的に自習を進めて下さい。 回 月 日 内 容 (予定) 月 日 内 容 (予定) レポート 9 12月4日 コマンドプロンプト操作 ディレクトリ移動、コンパイル、実行 10 12月11日 リダイレクト、パイプ 11 12月18日 第14章 ファイル操作(コマンドプロンプト版) 第3回レポート(必須) Excelとの連携、CSVファイル (1/8提出) 12 1月8日 Excelとの連携 リサージュ、対数グラフ 13 1月29日 第4回レポート(任意) 3次元グラフ (2/2提出) 14 2月2日 Gnuplotとの連携 デモ、各種グラフ 15 2月5日 期末テスト 各自のコースナビ「C言語入門編」の進度を毎週、発表予定。 積極的に自習を進めて下さい。
第17章 その他の制御文 17.1 do-while文 17.2 goto文とラベル 17.3 break文による繰返し制御 17.4 continue文による繰返し制御 17.5 return文
17.1 do-while文 #include <stdio.h> /* ex17_1_1.c */ p.161 例17.1.1 p.22 例5.1.1 #include <stdio.h> /* ex17_1_1.c */ int main(void) { int i; i = 0; do { printf("繰返し\n"); i = i + 1; } while (i < 10); return 0; } #include <stdio.h> /* ex5_1_1.c */ int main(void) { int i; i = 0; while (i < 10) { printf("繰返し\n"); i = i + 1; } return 0; 条件を満たさなくても1回は実行 条件を満たすときのみ実行 i = 10; とすると違いがわかる
17.1 do-while文 2) 12 #include <stdio.h> 2) 6...0 p.162 例17.1.2 2) 12 2) 6...0 2) 3...0 2) 1...1 0...1 #include <stdio.h> /* 整数の2進表現を下位から表示 */ int main(void) { int n, b; n = 12; do { b = n % 2; printf("%d\n", b); n /= 2; } while (n > 0); return 0; } while 文を使って 書き直せ n = 0 としたとき どうなるか? さらに… n = 0 としたときにも 同じ結果を得るには どうすればよいか?
17.2 goto文とラベル #include <stdio.h> /* ex17_2_1.c */ p.162 例17.2.1 p.22 例5.1.1 #include <stdio.h> /* ex17_2_1.c */ int main(void) { int i; i = 0; loop: if (i >= 10) goto next; printf("繰返し\n"); i = i + 1; goto loop; next: return 0; } #include <stdio.h> /* ex5_1_1.c */ int main(void) { int i; i = 0; while (i < 10) { printf("繰返し\n"); i = i + 1; } return 0;
17.2 goto文とラベル p.164 例17.2.2 i2 + j2 = k2 を満たす自然数の組を探す #include <stdio.h> #define MAX 10 /* ex17_2_2.c */ int main(void) { int i, j, k; for (k = 1; k < MAX; k++) { for (i = 1; i < k; i++) { for (j = i; j < k; j++) if (k * k == i * i + j * j) goto found; } printf("not found\n"); return 0; found: printf("%d * %d + %d * %d = %d * %d\n", i, i, j, j, k, k); i2 + j2 = k2 を満たす自然数の組を探す
17.3 break文による繰返し制御 #include <stdio.h> #define MAX 800 p.166 例17.3.2 17.3 break文による繰返し制御 #include <stdio.h> #define MAX 800 #define N 10 /* ex17_3_2.c */ int main(void) { int primes[MAX]; // 素数判定結果用配列 int i, j, p; // i: 範囲, p: 素数カウンタ for (i = 2; i < MAX; i++) primes[i] = 1; p = 0; 800未満の素数 10個ごとに改行 エラトステネスの篩(ふるい) "真"で初期化
17.3 break文による繰返し制御 for (i = 2; i < MAX; i++) { if (primes[i]) { printf("%5d", i); if ((++p) % N == 0) printf("\n"); if (p == 100) break; for (j = 2 * i; j < MAX; j += i) primes[j] = 0; // 偽 } return 0; 素数を印刷 N(=10)個ごとに改行 ループの 外に脱出 100個めで強制終了 ここで篩(ふるい)にかけている break は、ループ(iのfor文)の外に出る
17.4 continue文による繰返し制御 #include <stdio.h> #define MAX 100 p.169 例17.4.2 17.4 continue文による繰返し制御 #include <stdio.h> #define MAX 100 /* ex17_4_2.c */ int main(void) { int i, j, sum, total = 0; for (i = 2; i < MAX; i++) { sum = 0; 完全数を探し、その総和を求める 完全数: ある自然数に対して、その数以外の約数の和がその数に等しいもの
17.4 continue文による繰返し制御 for (j = 1; j < i; j++) if (i % j == 0) sum += j; if (sum != i) continue; printf("%d\n", i); total += i; } printf("total = %d\n", total); return 0; j が i の約数なら加算 完全数でないならスルー 完全数なら印刷 continue は、ループ(iのfor文)の最後に飛ぶ
17.5 return文 #include <stdio.h> #define NEGATIVE (-1) p.170 例17.5.1 #include <stdio.h> #define NEGATIVE (-1) /* ex17_5_1.c */ int factorial(int x); int main(void) { int x, y; printf("入力 = "); scanf("%d", &x); y = factorial(x); 階乗の計算
17.5 return文 if (y == NEGATIVE) printf("負の数が入力されました\n"); else printf("%d! = %d", x, y); return 0; } 入力値が負なら終了 入力値が正なら答えを印刷
17.5 return文 int factorial(int x) { 階乗の計算ルーチン int i, result = 1; if (x < 0) return NEGATIVE; if (x == 0) return result; else { for (i = 1; i <= x; i++) result *= i; return result; } 階乗の計算ルーチン 階乗計算 return は、その関数から抜けて、値を返す
第18章 マクロ 18.1 引数を持たないマクロ 18.2 引数を持つマクロ
18.1 引数を持たないマクロ #define PI 3.1415926 #define WORD 32 #define ROOT sqrt 例18.1.1 #define PI 3.1415926 #define WORD 32 #define ROOT sqrt #define NEWLINE printf("\n") int main(void) { double x, y; int w; x = PI * 2.0: y = ROOT(x); printf("%f\n", x); NEWLINE; w = WORD / 8; } ex18_1_1.c という名前で保存
18.1 引数を持たないマクロ Z:\nyumon2> cl -E ex18_1_1.c int main(void) { プリプロセッサの出力を表示 int main(void) { double x, y; int w; x = 3.1415926 * 2.0: y = sqrt(x); printf("%f\n", x); printf("\n"); w = 32 / 8; }
18.2 引数を持つマクロ #include <stdio.h> p.174 例18.2.1 #include <stdio.h> #define larger(x, y) (((x) > (y)) ? (x) : (y)) #define smaller(x, y) (((x) < (y)) ? (x) : (y)) int main(void) { int x[] = {6, 10, 4, 1, 3, 9, 11, 3, 20, 3, 4, 4, 6, 3, 2}; int n = sizeof x / sizeof x[0]; int i, max, min; max = min = x[0]; for (i = 1; i < n; i++) { max = larger(max, x[i]); min = smaller(min, x[i]); } printf("最大値 = %d\n", max); printf("最小値 = %d\n", min); return 0; if (max > x[i]) max = max; else max = x[i]; if (min < x[i]) min = min; else min = x[i];
数当てゲーム 人が思い浮かべた数をコンピュータが当てるプログラム #include <stdio.h> int loop(void); int check(int k); /* number.c */ int main(void) { printf("1~100までのうち、 数字を一つ思い浮かべてください。\n"); printf("%d回で当たりました!¥n", loop()); }
数当てゲーム(つづき) int loop(void) { int inc = 50, sgn, est = 50; int ans, nloop = 1; while (1) { ans = check(est); switch (ans) { case 0: return nloop; case 1: sgn = 1; break; case 2: sgn = -1; } inc /= 2; if (inc == 0) inc = 1; est += sgn * inc; nloop++; }
数当てゲーム(つづき) int check(int k) { int ans; do { printf("あなたの考えている数字は%dですか?\n", k); printf("はい=0, もっと大きい=1, もっと小さい=2: "); scanf("%d", &ans); } while ( ); return ans; } ? ans が 0~2 以外なら再入力させる 当てるまでの回数が多い → 改良の余地アリ