1 C言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。) 2 期末試験問題 3 第1週資料p.7. 問1はいつものコン パイル手順を思い 出してみると良い C言語のプログラム いつもgccや bcc32がやってく れている処理の 範囲 • コンパイラにより実行形式に変換する Source files .h ファイル .h ファイル .h ファイル Preprocessor Executable file C compiler 実行ファイル Object files .c ファイル .c ファイル .c ファイル .o ファイル .o ファイル .o ファイル linker 4 アセンブラ • 教科書p.17 • 第2週講義資料 pp.25-26. 5 第3週資料p.92. 初期化・更新処理付きループ (for 文) • 真偽値による繰り返し for(式1; 式2; 式3) { // 式2が真の場合の処理 }; 式1 式2 真 問2-1は、forループの処理手順を自分で 確かめれば良い 処理 式3 偽 6 問2-2 • y軸のカウントダウン(y--)が出来てない人 (b) が多数いた。 • 境界値の間違いが多数いた • <, <=, >=, > の違い • 例えば代表値を代入して確認してみる • 例: (x,y) = (0,0) や (7,7) 等 $ ./a 7 . . 6 . . 5 . . 4 . . 3 . . 2 . . 1 . # 0 # # y x 0 1 . . . . . # # # . . . . # # # # . . . # # # # # . . # # # # # # . # # # # # # # # # # # # # # # 2 3 4 5 6 7 (b) $ ./a 7 . . 6 . . 5 . . 4 . . 3 . . 2 . . 1 . # 0 # # y x 0 1 . . . . . # # # . . . . # # # # . . . # # # # # . . # # # # # # . # # # # # # # # # # # # # # # 2 3 4 5 6 7 7 問2-3 • 問2-1同様、1つ1つの手順に値を入れて自 分で手順を確認してみれば良い。 • 実は処理を1つ1つ確認しなくても選択ソート のアルゴリズム(=処理手順)を知っていれば 分かる問題 • 未処理の先頭値と、未処理の最小値を交換する 選択ソートの進捗 $ gcc exam_q2_3.c && ./a 0 3 13 2 7 17 11 19 5 1 2 13 3 7 17 11 19 5 2 2 3 13 7 17 11 19 5 3 2 3 5 7 17 11 19 13 4 2 3 5 7 17 11 19 13 5 2 3 5 7 11 17 19 13 6 2 3 5 7 11 13 19 17 7 2 3 5 7 11 13 17 19 赤字: 処理済み 青字: 未処理の先頭 橙字: 未処理の最小値 8 問3-1 • double なのに int にしている人が多数いた • 関数呼び出し時に & を付けない人が多数い た(ポインタ渡しにしないと、呼び出し元の変 数の内容を変更出来ない) 9 問3-2 • double tmp; と宣言しなければいけないの で tmp は double 型であってポインタでは ない。 • ポインタでない変数 tmp の前に間接参照の 単項演算子 '*' を付けているのでエラーと なった。 • tmp の前の '*' を除去して *b = tmp と すれば良い。 10 問4 • 以下の何れか • int factorize(int x, int a[], int n); • int factorize(int x, int *a, int n); • 末尾が ; 出ない人が多数いた • 適切に型を与えていない(intと書いていな い人)も多数いた • a が a[] や *a 出ない人が多数いた 11 問5 • ポインタ変数 p の使い方 • p : 代入したアドレスそのもの • *p : 代入したアドレスに格納されている値 • 例: • p = &a なら • p は a のアドレス(つまり &a) • *p は a の値(つまり a) 12 問5 • ポインタ変数 p の計算 • p + 1 は? • *p の次の要素のアドレス • つまりpに入っているアドレスにsizeof(*p)を加算し た値 • 例: • p = &a が 0 で sizeof(*p) が 4 なら • p + 1 は 4 13 問6-1 • 関数 main • s の先頭からサイズ-1(終端文字\0の手前)ま でを処理している • s の内容を1つづず q6_1 に与えて戻り値を文 字コードとして扱い、対応する文字を1文字表示 • 関数 q6_1 • abc~xyz が zyx~cba に入れ替わる • アルファベットの小文字以外はそのまま 14 問6-2 • 配列の初期化 • 第3週資料p.73-83.を参照 15 期末試験実技課題 16 統計 • 母集団のすべての標本値 𝑥𝑖 が𝑖 = 0~𝑛 − 1までの𝑛個あるとした場合 • (母集団の)平均 (AVR: AVeRage) 1 𝑥= 𝑛 • (母集団の)分散 (VAR: VARiance) 1 2 𝜎 = 𝑛 𝑛−1 値の合計値 件数 𝑥𝑖 𝑖=0 𝑛−1 𝑥𝑖 − 𝑥 2 各値 − 平均 2 の平均 𝑖=0 • (母集団の)標準偏差 (STDEV: STandard DEViation) 𝜎= 1 𝑛 𝑛−1 𝑥𝑖 − 𝑥 𝑖=0 2 分散の平方根 17 統計 • (母集団の)平均 (AVR: AVeRage) 1 𝑥= 𝑛 𝑛−1 𝑥𝑖 値の合計値 件数 𝑖=0 for による積算 sum = 0; for (i = 0; i < n; i++) { sum += x[i]; } avr = sum / n; 積算用変数の初期化 値の積算 値の合計値 件数 ここではsumがdouble型なので暗黙の算術変換(第5週資料p.49)が適用されるが、 「整数型 / 整数型」の場合は(double)等のキャストを行わないと結果が整数になる 18 統計 • (母集団の)分散 (VAR: VARiance) 1 𝜎 = 𝑛 𝑛−1 2 𝑥𝑖 − 𝑥 2 各値 − 平均 2 の平均 𝑖=0 for文による積算 var = 0; 積算用変数の初期化 for (i = 0; i < n; i++) { 値の積算 var += (x[i] - avr) * (x[i] - avr); } 値の合計値 var /= n; 件数 訂正: 2014-08-18 19:50 誤: (x[i] - var) 正: (x[i] - avr) 19 統計 • (母集団の)標準偏差 (STDEV: STandard DEViation) 𝜎= 平方根の計算 stdev = sqrt(var); 1 𝑛 𝑛−1 𝑥𝑖 − 𝑥 𝑖=0 2 分散の平方根 20 課題1: calcscore.c 全てまとめると完成 calcscore.c: 追記部分 sum = 0; for (i = 0; i < n; i++) { sum += score[i]; } avr = sum / n; var =0; for (i = 0; i < n; i++) { var += (score[i] - avr) * (score[i] - avr); } var = var / n; stdev = sqrt(var); 21 素因数分解 正整数𝑥を因数分解するには 1. 整数𝑦を2以上𝑥未満まで順に増やしながら手順2の 処理を繰り返す。 2. 𝑥が𝑦で割り切れるなら𝑥 = 𝑦 × 𝑧として𝑦を素因数と して保存し𝑧を新たな𝑥とする事を繰り返す。(12 = 2 × 2 ×3の同じ素因数を複数個取り得るため) 3. 最後に残った𝑥も素因数として保存する。ただし、 𝑥=1の場合、かつ保存した素因数が1個以上ある場 合𝑥を素因数として保存してはいけない。(4 = 2 × 2 × 1のようになるため) 例: 1 = 1 2 = 2 3 = 3 4 = 2 * 2 12 = 2 * 2 * 3 なおyを2~x未満とした場合 x=7をy=6で割るのは明らかに無駄だが ここでは手順の簡素化を優先している。 22 素因数分解 1. 整数𝑦を2以上𝑥未満まで順に増やしながら 手順2の処理を繰り返す。 for文を使って単純に繰り返せばよい 手順1のループ for (y = 2; y < x; y++) { // y を 2 以上 x 未満まで増やす }; 23 素因数分解 2. 𝑥が𝑦で割り切れるなら𝑥 = 𝑦 × 𝑧として𝑦を素因数と して保存し𝑧を新たな𝑥とする事を繰り返す。 ここも繰り返しなので手順1と手順2で2重ループとなる 素因数の保存は配列に追加して行けば良い 手順2のループ 保存済みの素因数をn個とした時 while (x % y == 0) { nは配列の最大要素数を超えてはいけないから // ここでyを保存 手順1のループ中で 処理する必要がある x = x / y; エラー処理も必要になる //zを新たなxにする } 24 素因数分解 2. 𝑥が𝑦で割り切れるなら𝑥 = 𝑦 × 𝑧として𝑦を素因数と 手順2におけるyの保存処理 して保存し𝑧を新たな𝑥とする事を繰り返す。 if (nmax <= n) return -1; a[n] = y; n++; ここも繰り返しなので手順1と手順2で2重ループとなる 素因数の保存は配列に追加して行けば良い 保存済みの素因数をn個とした時 nは配列の最大要素数を超えてはいけないから エラー処理も必要になる 25 素因数分解 2. 𝑥が𝑦で割り切れるなら𝑥 = 𝑦 × 𝑧として𝑦を素因数と して保存し𝑧を新たな𝑥とする事を繰り返す。 手順2の処理 ここも繰り返しなので手順1と手順2で2重ループとなる while (x % y == 0) { if素因数の保存は配列に追加して行けば良い (nmax <= n) return -1; a[n] = 保存済みの素因数をn個とした時 y; 手順1のループ中で 処理する必要がある n++; nは配列の最大要素数を超えてはいけないから x = x / y; エラー処理も必要になる } 26 素因数分解 3. 最後に残った𝑥も素因数として保存する。ただし、 𝑥=1の場合、かつ保存した素因数が1個以上ある場 合𝑥を素因数として保存してはいけない。 if 文で条件分岐させれば良い 条件は「𝑥=1かつ保存した素因数が1個以上ある」以外 の場合𝑥も素因数として保存するとも言い換えることが出 手順3の処理 来る。 if (!(x == 1 && 0 < n)) { 素因数の保存とエラー処理については if (nmax <= n + 1) return -1; 手順2と同じ a[n] = x; n++; } 27 課題2: factorize.c factoraize.c • 全てまとめると完成 int factorize(int x, int *a, int nmax) { int y, z, n = 0; if (x <= 0) return -1; for (y = 2; y < x; y++) { while (x % y == 0) { z = x / y; if (nmax <= n) return -1; a[n] = y; n++; x = z; } } if (!(x == 1 && 0 < n)) { if (nmax <= n + 1) return -1; a[n] = x; n++; } factoraize.h #ifndef FACTORIZE_H #define FACTORIZE_H int factorize(int x, int *a, int nmax); #endif return n; }
© Copyright 2025 ExpyDoc