27
C言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。) 1

C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

C言語入門 第17週 (補講)

プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ,

情報処理言語Ⅰ(実習を含む。)

1

Page 2: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

期末試験問題

2

Page 3: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

C言語のプログラム

• コンパイラにより実行形式に変換する

.c ファイル

.h ファイル .h ファイル

.h ファイル

.c ファイル .c ファイル

Source files

C compiler

Preprocessor

linker

.o ファイル

Object files

.o ファイル .o ファイル

実行ファイル

Executable file

3 第1週資料p.7.

いつもgccやbcc32がやってく

れている処理の範囲

問1はいつものコン

パイル手順を思い出してみると良い

Page 4: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

アセンブラ

• 教科書p.17

• 第2週講義資料 pp.25-26.

4

Page 5: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

初期化・更新処理付きループ (for 文)

• 真偽値による繰り返し

5

for(式1; 式2; 式3) { // 式2が真の場合の処理 };

式2

式1

問2-1は、forループの処理手順を自分で確かめれば良い

処理

式3

第3週資料p.92.

Page 6: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

問2-2

• y軸のカウントダウン(y--)が出来てない人が多数いた。

• 境界値の間違いが多数いた

• <, <=, >=, > の違い

• 例えば代表値を代入して確認してみる

• 例: (x,y) = (0,0) や (7,7) 等

6

(b) $ ./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

Page 7: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

問2-3

• 問2-1同様、1つ1つの手順に値を入れて自分で手順を確認してみれば良い。

• 実は処理を1つ1つ確認しなくても選択ソートのアルゴリズム(=処理手順)を知っていれば分かる問題

• 未処理の先頭値と、未処理の最小値を交換する

7

選択ソートの進捗 $ 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

赤字: 処理済み 青字: 未処理の先頭 橙字: 未処理の最小値

Page 8: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

問3-1

• double なのに int にしている人が多数いた

• 関数呼び出し時に & を付けない人が多数いた(ポインタ渡しにしないと、呼び出し元の変数の内容を変更出来ない)

8

Page 9: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

問3-2

• double tmp; と宣言しなければいけないので tmp は double 型であってポインタではない。

• ポインタでない変数 tmp の前に間接参照の単項演算子 '*' を付けているのでエラーとなった。

• tmp の前の '*' を除去して *b = tmp とすれば良い。

9

Page 10: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

問4

• 以下の何れか

• int factorize(int x, int a[], int n);

• int factorize(int x, int *a, int n);

• 末尾が ; 出ない人が多数いた

• 適切に型を与えていない(intと書いていない人)も多数いた

• a が a[] や *a 出ない人が多数いた

10

Page 11: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

問5

• ポインタ変数 p の使い方

• p : 代入したアドレスそのもの

• *p : 代入したアドレスに格納されている値

• 例:

• p = &a なら

• p は a のアドレス(つまり &a)

• *p は a の値(つまり a)

11

Page 12: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

問5

• ポインタ変数 p の計算

• p + 1 は?

• *p の次の要素のアドレス

• つまりpに入っているアドレスにsizeof(*p)を加算した値

• 例:

• p = &a が 0 で sizeof(*p) が 4 なら

• p + 1 は 4

12

Page 13: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

問6-1

• 関数 main

• s の先頭からサイズ-1(終端文字¥0の手前)までを処理している

• s の内容を1つづず q6_1 に与えて戻り値を文字コードとして扱い、対応する文字を1文字表示

• 関数 q6_1

• abc~xyz が zyx~cba に入れ替わる

• アルファベットの小文字以外はそのまま

13

Page 14: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

問6-2

• 配列の初期化

• 第3週資料p.73-83.を参照

14

Page 15: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

期末試験実技課題

15

Page 16: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

統計

• 母集団のすべての標本値 𝑥𝑖が𝑖 = 0~𝑛 − 1までの𝑛個あるとした場合 • (母集団の)平均 (AVR: AVeRage)

𝑥 =1

𝑛 𝑥𝑖

𝑛−1

𝑖=0

• (母集団の)分散 (VAR: VARiance)

𝜎2 =1

𝑛 𝑥𝑖 − 𝑥

2

𝑛−1

𝑖=0

• (母集団の)標準偏差 (STDEV: STandard DEViation)

𝜎 =1

𝑛 𝑥𝑖 − 𝑥

2

𝑛−1

𝑖=0

16

各値 −平均 2の平均

分散の平方根

値の合計値

件数

Page 17: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

統計

• (母集団の)平均 (AVR: AVeRage)

𝑥 =1

𝑛 𝑥𝑖

𝑛−1

𝑖=0

17

値の合計値

件数

for による積算 sum = 0; for (i = 0; i < n; i++) { sum += x[i]; } avr = sum / n; 値の合計値

件数

値の積算

積算用変数の初期化

ここではsumがdouble型なので暗黙の算術変換(第5週資料p.49)が適用されるが、「整数型 / 整数型」の場合は(double)等のキャストを行わないと結果が整数になる

Page 18: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

統計

• (母集団の)分散 (VAR: VARiance)

𝜎2 =1

𝑛 𝑥𝑖 − 𝑥

2

𝑛−1

𝑖=0

18

各値 −平均 2の平均

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)

Page 19: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

統計

• (母集団の)標準偏差 (STDEV: STandard DEViation)

𝜎 =1

𝑛 𝑥𝑖 − 𝑥

2

𝑛−1

𝑖=0

19

分散の平方根

平方根の計算 stdev = sqrt(var);

Page 20: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

課題1: calcscore.c

全てまとめると完成

20

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);

Page 21: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

素因数分解

正整数𝑥を因数分解するには

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

21

なおyを2~x未満とした場合 x=7をy=6で割るのは明らかに無駄だが ここでは手順の簡素化を優先している。

Page 22: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

素因数分解

1. 整数𝑦を2以上𝑥未満まで順に増やしながら手順2の処理を繰り返す。

for文を使って単純に繰り返せばよい

22

手順1のループ for (y = 2; y < x; y++) { // y を 2 以上 x 未満まで増やす };

Page 23: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

素因数分解

2. 𝑥が𝑦で割り切れるなら𝑥 = 𝑦 × 𝑧として𝑦を素因数として保存し𝑧を新たな𝑥とする事を繰り返す。

ここも繰り返しなので手順1と手順2で2重ループとなる

素因数の保存は配列に追加して行けば良い

保存済みの素因数をn個とした時

nは配列の最大要素数を超えてはいけないから

エラー処理も必要になる

23

手順2のループ while (x % y == 0) { // ここでyを保存 x = x / y; //zを新たなxにする }

手順1のループ中で 処理する必要がある

Page 24: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

素因数分解

2. 𝑥が𝑦で割り切れるなら𝑥 = 𝑦 × 𝑧として𝑦を素因数として保存し𝑧を新たな𝑥とする事を繰り返す。

ここも繰り返しなので手順1と手順2で2重ループとなる

素因数の保存は配列に追加して行けば良い

保存済みの素因数をn個とした時

nは配列の最大要素数を超えてはいけないから

エラー処理も必要になる

24

手順2におけるyの保存処理 if (nmax <= n) return -1; a[n] = y; n++;

Page 25: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

素因数分解

2. 𝑥が𝑦で割り切れるなら𝑥 = 𝑦 × 𝑧として𝑦を素因数として保存し𝑧を新たな𝑥とする事を繰り返す。

ここも繰り返しなので手順1と手順2で2重ループとなる

素因数の保存は配列に追加して行けば良い

保存済みの素因数をn個とした時

nは配列の最大要素数を超えてはいけないから

エラー処理も必要になる

25

手順2の処理 while (x % y == 0) { if (nmax <= n) return -1; a[n] = y; n++; x = x / y; }

手順1のループ中で 処理する必要がある

Page 26: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

素因数分解

3. 最後に残った𝑥も素因数として保存する。ただし、 𝑥=1の場合、かつ保存した素因数が1個以上ある場合𝑥を素因数として保存してはいけない。

if 文で条件分岐させれば良い 条件は「𝑥=1かつ保存した素因数が1個以上ある」以外

の場合𝑥も素因数として保存するとも言い換えることが出来る。

素因数の保存とエラー処理については 手順2と同じ

26

手順3の処理 if (!(x == 1 && 0 < n)) { if (nmax <= n + 1) return -1; a[n] = x; n++; }

Page 27: C言語入門 - Yamaguchi Uweb.cc.yamaguchi-u.ac.jp/~okadalab/CLangI2014/... · c言語入門 第17週 (補講) プログラミング言語Ⅰ(実習を含む。), ... 単項演算子

課題2: factorize.c

• 全てまとめると完成

27

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++; } return n; }

factoraize.h #ifndef FACTORIZE_H #define FACTORIZE_H int factorize(int x, int *a, int nmax); #endif