1 C言語入門 第5週 プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。) 2 入れ子の繰り返し(多重ループ) 3 多重ループとは? • ループの中に別のループを入れた 入れ子構造のループ mul99_ex1.c 7 for (i = 1; i <= 9; i++) { //行ループ 8 for (j = 1; j <= 9; j++) {//列ループ 9 printf(" %2d", i * j); //掛算九九 10 } 11 printf("\n"); //行末尾で改行 12 } 上記は掛算九九を計算して表を作成する例 mintty + bash $ gcc mul99_ex1.c && ./a 1 2 3 4 5 6 7 8 2 4 6 8 10 12 14 16 3 6 9 12 15 18 21 24 4 8 12 16 20 24 28 32 5 10 15 20 25 30 35 40 6 12 18 24 30 36 42 48 7 14 21 28 35 42 49 56 8 16 24 32 40 48 56 64 9 18 27 36 45 54 63 72 9 18 27 36 45 54 63 72 81 4 掛算九九の例 • 見出し行と見出し列、見出し区切り(-+|)を付 けた例 7 8 9 10 11 12 13 14 15 16 17 mul99_ex2.c mintty + bash printf(" |"); //見出しの区切り for (j = 1; j <= 9; j++) { printf(" %2d", j); //見出し } printf("\n"); //見出しの改行 $ gcc mul99_ex2.c && ./a | 1 2 3 4 5 6 7 8 9 --+--------------------------1| 1 2 3 4 5 6 7 8 9 2| 2 4 6 8 10 12 14 16 18 3| 3 6 9 12 15 18 21 24 27 4| 4 8 12 16 20 24 28 32 36 5| 5 10 15 20 25 30 35 40 45 6| 6 12 18 24 30 36 42 48 54 7| 7 14 21 28 35 42 49 56 63 8| 8 16 24 32 40 48 56 64 72 9| 9 18 27 36 45 54 63 72 81 printf("--+"); //見出しの区切り for (j = 1; j <= 9; j++) { printf("---"); //見出しの区切り } printf("\n"); //見出しの区切りの改行 5 掛算九九の例 • 見出し行と見出し列、見出し区切り(-+|)を付 けた例 mul99_ex2.c 19 for (i = 1; i <= 9; i++) {//行ループ 20 printf("%2d|", i); //見出しと区切り 21 for (j = 1; j <= 9; j++) {//列ループ 22 printf(" %2d", i * j); //掛算九九 23 } 24 printf("\n"); //行末尾で改行 25 } mintty + bash $ gcc mul99_ex2.c && ./a | 1 2 3 4 5 6 7 8 9 --+--------------------------1| 1 2 3 4 5 6 7 8 9 2| 2 4 6 8 10 12 14 16 18 3| 3 6 9 12 15 18 21 24 27 4| 4 8 12 16 20 24 28 32 36 5| 5 10 15 20 25 30 35 40 45 6| 6 12 18 24 30 36 42 48 54 7| 7 14 21 28 35 42 49 56 63 8| 8 16 24 32 40 48 56 64 72 9| 9 18 27 36 45 54 63 72 81 6 while 文の2重ループの例 2重ループ while (条件式1) { // 処理1-1 while (条件式2) { // 処理2 // ... // ... // ... } // 処理1-2 } 1 条件式1 条件式2 真 処理1-1 真 処理2 1 2 2 処理1-1 ループは基本的にいくつでも 入れ子に出来る。 偽 偽 7 while 文の3重ループの例 3重ループ while (条件式1) { // 処理1-1 while (条件式2) { // 処理2-1 while (条件式3) { // 処理3 } // 処理2-2 } // 処理1-2 } 入れ子があまり深くなると 分かり辛くなるので注意 1 条件式1 偽 2 条件式2 真 真 処理1-1 処理2-1 1 2 偽 条件式2 真 処理2 3 4 3 処理1-1 処理2-1 4 偽 8 異なるループ文で多重ループ • do-while, while, for ループを必要に応じて組 み合わせて入れ子にする 異なるループ文で3重ループ 異なるループ文で3重ループ for (式1-1; 式1-2; 式1-3) { // 処理1-1 while (条件式2) { // 処理2-1 do { // 処理3 } while (条件式3); // 処理2-2 } // 処理1-2 } do { // 処理1-1 for (式2-1; 式2-2; 式2-3){ // 処理2-1 while (条件式3) { // 処理3 } // 処理2-2 } // 処理1-2 } while (条件式1); 9 多重ループの例題 掛算九九の表 10 演習: 掛算九九(範囲指定) • 標準入力から掛算九九の表の表示範囲 i1 i2 j1 j2 を読み取り、指定された範囲 のみ表示する mul99_practice_1.c を作 成せよ(/*WYCH*/ の個所を修正すれば良 い)。 mintty + bash 値が3桁やマイナスになると 表示が破綻する場合があるが、 以下で行う一連の演習では 3桁やマイナスの値は考慮しなくて良い。 $ gcc mul99_practice_1.c && ./a i1 i2 j1 j2 = 2 5 4 8 | 4 5 6 7 8 --+--------------2| 8 10 12 14 16 3| 12 15 18 21 24 4| 16 20 24 28 32 5| 20 25 30 35 40 11 演習: 掛算九九(行の反転) • 完成した mul99_practice_1.c をコピーし てファイル名を mul99_practice_2.c とし、 行の見出しが逆順となるよう修正せよ。 mintty + bash $ gcc mul99_practice_2.c && ./a i1 i2 j1 j2 = 2 5 4 8 | 4 5 6 7 8 --+--------------5| 20 25 30 35 40 4| 16 20 24 28 32 3| 12 15 18 21 24 2| 8 10 12 14 16 12 演習: 掛算九九(見出しの移動) • 完成した mul99_practice_2.c をコピーし てファイル名を mul99_practice_3.c とし、 列の見出しを表の下に表示するよう修正せよ。 mintty + bash $ gcc mul99_practice_3.c && ./a i1 i2 j1 j2 = 2 5 4 8 5| 20 25 30 35 40 4| 16 20 24 28 32 3| 12 15 18 21 24 2| 8 10 12 14 16 --+--------------| 4 5 6 7 8 13 演習: 掛算九九(表示値の制限) • 完成した mul99_practice_3.c をコピーし てファイル名を mul99_practice_4.c とし、 i*j<=99の場合以外は結果を "##" と表示 するよう修正せよ。 mintty + bash $ gcc mul99_practice_4.c && ./a i1 i2 j1 j2 = 8 14 5 15 14| 70 84 98 ## ## ## ## ## ## ## ## 13| 65 78 91 ## ## ## ## ## ## ## ## 12| 60 72 84 96 ## ## ## ## ## ## ## 11| 55 66 77 88 99 ## ## ## ## ## ## 10| 50 60 70 80 90 ## ## ## ## ## ## 9| 45 54 63 72 81 90 99 ## ## ## ## 8| 40 48 56 64 72 80 88 96 ## ## ## --+--------------------------------| 5 6 7 8 9 10 11 12 13 14 15 14 多重ループの例題 画像の生成 15 BMP, DIB • Wikipedia / Windows bitmap • Windows 標準の画像形式 • 書くのは比較的簡単 • 例: 第1週の bmptest.c 等 • 読むのは、フォーマットがいくつもあるので、全部 対応するのは面倒 16 PNM(Portable aNyMap) • Wikipedia / PNM (画像フォーマット) • シンプルなフォーマットで読み書きが簡単 ファイル識別子 画像形式 データ形式 f.pbm P1 PBM: Portable Bit Map テキスト P2 PGM: Portable Gray Map テキスト P3 PPM: Portable Pix Map テキスト P4 PBM: Portable Bit Map バイナリ P5 PGM: Portable Gray Map バイナリ P6 PPM: Portable Pix Map バイナリ P1 # f.pbm 6 7 0 0 0 0 0 1 1 1 0 1 0 0 0 1 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 17 テキスト形式の PBM Format • 2値(白黒)画像用 feep.pbm P1 # feep.pbm 24 7 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ファイル識別子 コメント 0 0 0 0 0 0 0 画像サイズ(幅と高さ) 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 1 1 1 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 1 1 1 0 1 0 0 0 0 0 1 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 0 1 0 0 0 0 1 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 2値画像データ本体 0または1のデータ 18 テキスト形式の PGM Format • 濃淡値(グレイスケール)画像用 濃淡値画像データ本体 数値が大きいものほど明るい feep.pgm P2 # feep.pgm 24 7 15 0 0 0 0 0 3 3 3 0 3 0 0 0 3 3 3 0 3 0 0 0 3 0 0 0 0 0 0 ファイル識別子 コメント 画像サイズ(幅と高さ) 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 7 7 7 7 0 0 7 0 7 0 7 0 0 7 0 7 0 7 0 0 7 0 0 0 7 0 0 0 0 0 0 0 0 明るさの最大値 0 0 0 0 0 0 11 11 11 11 0 11 0 0 0 0 11 11 11 0 0 11 0 0 0 0 11 11 11 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 15 15 0 15 15 15 0 15 0 0 0 19 テキスト形式の PPM Format • カラー画像用 feep.ppm P3 # feep.ppm 4 4 15 0 0 0 0 0 0 0 0 0 15 0 15 ファイル識別子 コメント 画像サイズ(幅と高さ) 0 0 0 15 0 0 0 0 0 7 0 0 0 0 0 0 0 15 0 0 0 0 7 0 15 0 0 0 明るさの最大値 0 15 0 0 カラー画像データ本体 0 0 RGBを1組にして書く 0 0 20 PNMからBMPへの変換 • netpbm または ImageMagick を使うと楽 • Wikipedia / netpbm • Wikipedia / ImageMagick • インストールは以下 mintty + bash apt-cyg install netpbm apt-cyg install ImageMagick 21 PNMからBMPへの変換 • ImageMagick を使った場合 パイプした結果を 標準入力から読み込む mintty + bash $ ./a | convert - image.bmp pnm を テキスト出力する プログラム 変換結果を保存する BMP ファイル名 22 演習: 円の描画(1/2) • pbm_practice_1.c の /*WYCH*/ の箇所を修 正し、中心座標(0,0)半径rの円の内部を0外 部を1とし x1,x2,y1,y2 の範囲について P1 形 式の PBM 画像を出力するプログラムを作成 せよ。 • ここでは円の内部をx 2 + y 2 < r 2 を定義し、 境界部分は内部に含めない事とする。またx 座標は右向き、y座標は下向きを正の方向と する。 23 演習: 円の描画(2/2) x1 x2 y1 • 出力結果の例 y2-y1+1 (0,0) r y2 mintty + bash mintty + bash $ gcc pbm_practice_1A.c && ./a x1 x2 y1 y2 r = -5 5 -5 5 4 P1 11 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 $ gcc pbm_practice_1A.c && ./a | convert - result.bmp x1 x2 y1 y2 r = -5 5 -5 5 4 24 発展問題 • pbm_practice_1.c を改造して■▲★等を描い てみよう 25 参考文献 • [1] B.W.カーニハン/D.M.リッチー著 石田晴久 訳、プログラミング言語C 第2版 ANSI 規格準 拠、共立出版(1989)
© Copyright 2024 ExpyDoc