計算機実習 I

第十一回 (2014 年 6 月 19 日)

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

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

Martin J. Dürst

AGU

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

目次

ミニテスト

前回のまとめ

前回の演習

 

ポインタの用途

自然言語での参照

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

値渡し (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 以外のプログラミング言語

@@@@in 2015, use 11C2_with_trace.c to show what happens

言語による差の具体例

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

 

今日の演習

次回の準備