18
ププププププププププ 11 プ ププププ(2) ププ プププププ ププ [email protected]

プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

Embed Size (px)

DESCRIPTION

プログラミング演習 Ⅱ 第 11 回 ポインタ(2). 情報・知能工学系 山本一公 [email protected]. 前回の課題の解説・ポイント(1). 課題9-1 p.228 、 List 10-2 を参考に作成 printf () のアドレスを表示するための変換指定子は “%p” 全ての変数が連続した領域に確保されるわけでは ない ことが分かる 隙間があいている コンピュータがアクセスし易いように割りつけられる 配列 は 必ず 連続 した領域に確保 される. 前回の課題の解説・ポイント(2). 課題9-2 月日数が 31 日でない月の処理に注意 - PowerPoint PPT Presentation

Citation preview

Page 1: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

プログラミング演習Ⅱ第 11 回

ポインタ(2)

情報・知能工学系山本一公

[email protected]

Page 2: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

前回の課題の解説・ポイント(1)• 課題9-1

– p.228 、 List 10-2 を参考に作成– printf() のアドレスを表示するための変換指定

子は “ %p”

– 全ての変数が連続した領域に確保されるわけではないことが分かる• 隙間があいている

– コンピュータがアクセスし易いように割りつけられる• 配列は必ず連続した領域に確保される

Page 3: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

前回の課題の解説・ポイント(2)• 課題9-2

– 月日数が 31 日でない月の処理に注意• 特に閏日がある 2 月

– 閏年の判定方法• 現在の暦(グレゴリオ暦)では

– 西暦年が 4 で割り切れる年は閏年– ただし、西暦年が 100 で割り切れる年は平年– ただし、西暦年が 400 で割り切れる年は閏年

• if ((*y % 4 == 0) && (*y % 100 != 0) || (*y % 400 == 0)) {…

Page 4: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

課題8の採点結果から(1)• 課題8-1

– 関数の中で変換用の文字配列を用意していると、処理できる文字列の長さがその配列の大きさで制限されることになる• 汎用性が下がる• 元の文字配列上で 1 文字ずつ直接入れ替えれば、

文字列の長さに依存しない

Page 5: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

課題8の採点結果から(2)• 課題8-2

– toupper() / tolower() は関数の中で行わないと意味がない• 問題で指定された関数を作成しましょう

– 一致・不一致の判定が最後の行の結果だけに依存しているプログラムがあった

– 長さの違うファイルをきちんと扱えていない• File1 の後ろに何かを付け足して File2 を作って比較すると、

一致判定を出すプログラムが多かった

– パターンをいろいろ考えてテストすべき

Page 6: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

今日の内容• 教科書 pp.238 ~ 245• ポインタと配列

• ポインタの型• ポインタと配列• 配列の受渡し

Page 7: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

ポインタの型• p.239, List 10-9 のプログラム

– warning は出るものの、コンパイルできるし、

動かすこともできる– しかし、 sizeof(int) と sizeof(double) が異

なっているので、上手く動いていない– int と double なのだから、ある意味当然か

• ポインタの型が問題になりやすいのは、ポインタ演算を行う場合– 配列をやると分かりやすい……かな?

Page 8: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

ポインタと配列(1)• p.240, List 10-10• ptr = &vc[0] と初期化

• “ptr + i” は、 ptr が指すオブジェクト(ここでは配列 vc[] の先頭)の i 個後ろの要素を指すポインタとなる– すなわち、 *(ptr + i) vc[i] ⇒ と同じ

Page 9: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

ポインタと配列(2)• ここで「ポインタの型」の話に戻る• “ptr + i” は、

“メモリ上のアドレス ptr の i 番地後ろ”ではなくて、 “ ptr が指すオブジェクトの i 個後ろの要素”である– アドレスを決定するためには、1個のオブ

ジェクトの大きさが分からないといけない– それを決めているのが「ポインタの型」

Page 10: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

ポインタと配列(3)• “float *ptr” だったら、 sizeof(float) は

4 [Byte] なので、“ ptr + 1” の実際のアドレスは、 ptr に“ 4” を加えたものになる

• “double *ptr” だったら、 sizeof(double) は8 [Byte] なので、“ ptr + 1” の実際のアドレスは、 ptr に“ 8” を加えたものになる

• ポインタの型を正しく与えておけば、このような計算は自動で正しく行われる

Page 11: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

ポインタと配列(4)• いちいち “ &vc[0]” って書くの面倒だよね

• “vc” とだけ書くと “ &vc[0]” と同じ意味になる!– 例外1:“ sizeof(vc)” の場合– 例外2:“ &vc” の場合

• p.243, Column 10-2– ポインタは単なるアドレスなので、配列の大きさ

(領域)に対する配慮はプログラマが自分でしなければならない• それが “参照” との違い

Page 12: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

配列の受渡し(1)• 関数のところでやった、配列の受渡し

– 関数定義側では、” []” だけを付ける

• 要素数を書いても間違いではない– 呼び出し側では” []” を付けない

int function(int x[], int no) /* int *x でも良いが、 厳密には意味が異なる */{ return x[no];}

int array[100], num, value;

value = function(array, num);

Page 13: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

配列の受渡し(2)• 呼出し側

– 配列名だけ書いているので、“ array” は “ &array[0]” と同じ意味になり、配列の先頭アドレスを指す ⇒ それを関数に渡している

int array[100], num, value;

value = function(array, num);

Page 14: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

配列の受渡し(3)• 受け取り側

– 通常、“ x[]” と “ *x” は別物である• 配列変数は const である

– 関数の仮引数では、同じもの(単なるアドレスの受渡し)になる

int function(int x[], int no) /* 仮引数の場合のみ、 int *x でも同じ意味に */{ return x[no];}

Page 15: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

今週の課題(1)1. 要素数 n の double 型配列 array に入っている数値の平均を求めて返す関数 double ave(double *array, int n) を作成せよ。ただし、これはポインタを上手く扱えるようになるための演習課題なので、 ave 関数中で“ [” “]” を使用してはならない。 main 関数等も作成して、完成したプログラムを作成すること。

2. 要素数 n の int 型配列 array に入っている数値を昇順(小→大の順)に並べ替えて array に上書き格納する関数 void sort(int *array, int n) を作成せよ。ただし、こちらも、 sort 関数中で“ [” “]” を使用してはならない。 main 関数等も作成して、完成したプログラムを作成すること。

Page 16: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

今週の課題(2)• 課題10-2のためのソートアルゴリズム

– 何でも良い。適当に調べたものを使え。ネットで見つけたソースコードを参考にしても良い。

– 分からない人は以下のアルゴリズム(選択ソート)を使え

1. n 個の要素の中で一番小さい値を探し、 1 番目の要素と交換する

2. 以下、 k=2 ~ n-1 まで「 k 番目から n 番目までの要素の中から一番小さい値を探し、 k 番目の要素と交換する」ことを繰り返す

Page 17: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

レポートについて• 電子メールで提出

– 提出先は [email protected]– Subject を「プログラミング演習2 課題 10提出 学籍番号・氏名 」とすること

– C言語ソースファイルを添付する• メールの本文には何も書かなくて良いです

– ソースファイルの頭にコメントで以下の情報を入れる• 学籍番号・氏名• プログラムの説明(どのように動くのか、工夫した点等)• 実行結果(長い場合は一部)を貼る

– 提出締切は、 1 月 23 日(水) 12:00 (1週間後)

Page 18: プログラミング演習 Ⅱ 第 11 回 ポインタ(2)

授業用 Webサイト• URL:

http://www.slp.cs.tut.ac.jp/~kyama/programming2/– 課題の pdf ファイルが置いてあります。– 授業で使った ppt ファイルを置いていきます。

• 質問メールは、以下のどちらかのアドレスまで– [email protected][email protected]

• C-515へ直接質問しに来ても構いません