計算機実習 I

第十一回 (2015 年 6 月 18 日)

ポインタの応用: 参照と間接

http://www.sw.it.aoyama.ac.jp/2015/CP1/lecture11.html

Martin J. Dürst

AGU

© 2005-15 Martin J. Dürst 青山学院大学

目次

ミニテスト

前回のまとめ

 

前回の演習結果

10A1 10B2 10C1 10C2
100点 81 41 20 1
60点 12 51 65 19
エラー 1 - 2 42
未提出 - 2 9 32

 

10C2 の注意点

[昨年度資料につき削除]

ポインタの用途

 

自然言語での参照

 

引数の値渡しと参照渡しのイメージ

値渡し (call by value):

  1. 付箋に値を書いて、捨ててもいいように渡す
  2. 修理するものを直接渡す (例: 靴の修理)

参照渡し (call by reference):

  1. 箱の中に値を用意し、箱の場所を渡す
  2. 修理する場所 (住所) を指定 (例: 道路や水道管の修理)

 

引数の参照渡し

参照渡しの定石 (配列以外)

 

参照渡しの定石 (配列)

 

配列の値渡しの方法

  1. 参照渡し、関数内で変更しない
  2. (1) で const で変更しないことを宣言、確認
  3. 関数に渡す前にコピー
  4. 配列を構造体のメンバで定義、構造体を渡す

 

参照渡しの応用例: 複数の戻り値

課題: ある関数で n2 と n3 を同時に返す

解決策: 初期されてない参照渡し:

void square_cube(int n, int *pn2, int *pn3)
{
*pn2 = n * n;
*pn3 = *pn2 * n;
}

呼び出し側:

int a=5, a2, a3;
square_cube(a, &a2, &a3);
printf("a=%d, a*a=%d, a*a*a=%d\n", a, a2, a3);

 

間接 (indirection)

名言: 「全ての情報テクノロジーの問題は間接のレベルを一つ増やせば解決可能」

間接の例:

C の場合には間接をポインタで実現

 

間接の応用例

順番を入れ替える時に、実際のデータを入れ替えると:

間接を使えば全ての問題が解決 (例: 11C2)

 

引数としての関数

関数 (のポインタ) も引数として関数に渡せる

典型例: あるパターンで仕事して欲しいが、具体的な仕事が未定

応用例: 相模原キャンパスの全ての講堂にある仕事をして欲しい

解決作:

 

様々な整列の実装

 

比較関数の導入

 

関数に関数を渡す
C 以外のプログラミング言語

 

言語による差の具体例

Ruby: students.sort { |a, b| a.number <=> b.number }

C 言語 (11C2 から):

int compareNumbers (const void* a, const void* b)
{
Student *studentPa = *((Student **) a);
Student *studentPb = *((Student **) b);

return strcmp (studentPa->studentNumber,
studentPb->studentNumber);
}
... qsort(byNumber, studentCount, sizeof(Student*), compareNumbers);

 

今日の演習

 

次回の準備