第17章 その他の制御文 17.1 17.2 17.3 17.4 17.5 do-while文 goto文とラベル break文による繰返し制御 continue文による繰返し制御 return文 17.1 do-while文 #include <stdio.h> /* ex17_1_1.c */ int main(void) { int i; 条件を満たさなく i = 0; ても1回は実行 do { printf("繰返し\n"); i = i + 1; } while (i < 10); return 0; } i = 10; とすると違いがわかる p.161 例17.1.1 p.22 例5.1.1 #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.1 do-while文 p.162 例17.1.2 2) 12 #include <stdio.h> 2) 6...0 /* 整数の2進表現を下位から表示 */ 2) 3...0 int main(void) 2) 1...1 { 0...1 int n, b; while 文を使って n = 12; n = 0 としたとき 書き直せ do { どうなるか? b = n % 2; さらに… printf("%d\n", b); n = 0 としたときにも n /= 2; 同じ結果を得るには どうすればよいか? } while (n > 0); return 0; } 17.2 goto文とラベル #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; } p.162 例17.2.1 p.22 例5.1.1 #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 #include <stdio.h> #define MAX 10 /* ex17_2_2.c */ i2 + j2 = k2 を満たす自然数の組を探す 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); return 0; } p.166 例17.3.2 17.3 break文による繰返し制御 #include <stdio.h> 800未満の素数 #define MAX 800 10個ごとに改行 #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; "真"で初期化 17.3 break文による繰返し制御 for (i = 2; i < MAX; i++) { 素数を印刷 if (primes[i]) { N(=10)個ごとに改行 printf("%5d", i); if ((++p) % N == 0) printf("\n"); ループの 100個めで強制終了 外に脱出 if (p == 100) break; for (j = 2 * i; j < MAX; j += i) primes[j] = 0; // 偽 ここで篩(ふるい) にかけている } } return 0; break は、ループ(iのfor文)の外に出る } 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++) j が i の約数 if (i % j == 0) sum += j; なら加算 if (sum != i) continue; 完全数でない ならスルー printf("%d\n", i); total += i; 完全数なら印刷 } printf("total = %d\n", total); return 0; } continue は、ループ(iのfor文)の最後に飛ぶ p.170 例17.5.1 17.5 return文 #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 引数を持たないマクロ p.172 例18.1.1 #define PI 3.1415926 ex18_1_1.c という名前で保存 #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; } 18.1 引数を持たないマクロ Z:\nyumon2> cl -E ex18_1_1.c プリプロセッサの出力を表示 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 引数を持つマクロ 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, int n = sizeof x / sizeof x[0]; int i, max, min; max = min = x[0]; if (max > x[i]) max for (i = 1; i < n; i++) { else max max = larger(max, x[i]); min = smaller(min, x[i]); if (min < x[i]) min } else min printf("最大値 = %d\n", max); printf("最小値 = %d\n", min); return 0; } 3, 2}; = max; = x[i]; = min; = x[i]; デバッグ用マクロ __FILE__: ファイル名(文字列) __LINE__: コードの行数(整数) __DATE__: コンパイルの日付(文字列) __TIME__: コンパイルの時間(文字列) 定義の例 #define CLINE printf(__FILE__":%d\n",__LINE__) #define DTIME printf(__DATE__" ["__TIME__"]\n") デバッグ用マクロ #include <stdio.h> #include <math.h> #define CLINE(x) fprintf(stderr,__FILE__":%d\n",__LINE__) int main(void) { double a = 1, b = 0, c = -1; printf("ここまでOK?\n"); CLINE; printf("a / b = %f\n", a / b); CLINE; printf("sqrt(c) = %f\n",sqrt(c)); CLINE; return 0; } テスト用関数 assert() #include <stdio.h> コメントをはずせばassertが無効に… //#define NDEBUG assert用ヘッダファイル #include <assert.h> #define VERSION printf(__FILE__": "__DATE__" ["__TIME__"]\n") int main(void) { double a=1, b=0, c; VERSION; printf("ここまでOK?\n"); assert( b != 0 ); // 条件を満たさない場合に異常終了 c = a / b; printf("a / b = %f\n", c); return 0; } ゲームの準備 乱数の発生(再掲) 制御コード WAVファイルの再生 列挙型 system関数 ■ 乱数の発生 p.183 int rand(void) 疑似乱数の発生 範囲:0~RAND_MAX(=32767) <stdlib.h>内で宣言 void srand(unsigned n) 疑似乱数のシード(種)の指定・変更 <stdlib.h>内で宣言 time_t time(time_t *timer) 経過時間を秒単位で表した数値 引数は NULL (空ポインタ)でよい <time.h>内で宣言 現在時間を使って 乱数の種を決定 サイコロ・プログラム(dice.c) #include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int i; /* 実行するたびに違う値が得られるように、 * 現在の時刻値を使って乱数ジェネレータを初期化 */ srand((unsigned)time(NULL)); /* サイコロを10回振る */ for (i = 0; i < 10; i++) printf("%d ", (rand() % 6) + 1); // 6の剰余系+1 printf("\n"); return 0; } ■ 制御コード 教科書 p.180, 表A.2: 制御コード \a ベル・警告音の出力 \r 行頭に戻る(キャリッジ・リターン) \f そのままの位置で行送り(ライン・フィード) \n 改行(\r\f) \t 水平タブ 使用例 putchar('\a'); printf("現在 %d 回目\r\a", i); サイコロ・プログラム2(dice2.c) #include <stdlib.h> #include <stdio.h> #include <time.h> int main(void) { int i, n, m; /* 現在の時刻値を使って乱数ジェネレータを初期化 */ srand((unsigned)time(NULL)); printf(" ---\n"); n = rand() % 6; m = n + 8 + rand() % 10; for (i = n; i < m; i++) n=0~5 m = n+8 ~ n+17 printf("\r| %d |\a", i % 6 + 1); printf("\n ---\n"); 1回の alert に約200 ms かかる return 0; → このサイコロは1.6 ~3.4秒間転がる } WAVファイルの再生 /* WAVファイルの再生 */ #include <windows.h> #pragma comment(lib,"winmm") // winmm.lib をリンクする int main(void) { if (!PlaySound("kidou.wav", 0, SND_FILENAME)) printf("The sound didn't play."); if (!PlaySound("shuryo.wav", 0, SND_FILENAME)) printf("The sound didn't play."); return 0; } C:\WINDOWS\Media フォルダにシステムが用いるサウンドファイルがある。 C:\Program Files\Microsoft Office\OFFICE11\MEDIA フォルダ ■ 列挙型 名前付き定数をゼロからの整数に対応させる enum タグ {列挙子リスト}; 例: enum DAYS { SUNDAY, MONDAY, ..., SATURDAY }; 実体→ 0, 1, ..., 6 ■ system関数 OS(コマンドプロンプト)のコマンドをプログラム の中から実行できる。 system("cls") で画面クリア #include <stdlib.h> が必要 ■スキルアップタイム 「地底探検ゲーム」のプログラムにおいて、地底 マップを毎回描き換えるようにsystem関数を用 いて改良せよ。 本日のパズル このプログラムは何を出力するか #include <stdio.h> #define PRINT2(fmt,x1,x2) printf("%"#fmt", %"#fmt"\n",x1,x2) int main(void) { static struct S1 {char c[4], *s;} s1 = { "abc", "def" }; static struct S2 {char *cp; struct S1 ss1; } s2 = { "ghi", { "jkl", "mno" } }; PRINT2(c, PRINT2(s, PRINT2(s, PRINT2(s, return 0; } s1.c[0], *s1.s); s1.c, s1.s); s2.cp, s2.ss1.s); ++s2.cp, ++s2.ss1.s); 1. 2. 3. 4.
© Copyright 2024 ExpyDoc