第十回 12 月 22 日

4 ポインタ

4.9 関数へのポインタ

関数へのポインタとは, 関数の実体(コンピュータのメモリ上のどこかに存在する) 関数の先頭アドレスを値として持つポインタのことである。 配列,例えば array[3] が定義されているとき, array は配列の先頭要素を指すアドレスである。 それと同様に,関数名は実際にはメモリ内にあるその関数の実行コードの先頭アドレスである。 関数へのポインタは, 別の関数にその値を渡したり, 関数からの戻り値として返したり, 配列に格納したり, 他の関数へのポインタに代入したりできる。

関数へのポインタを説明するために, 再帰のところで取り上げたクイックソートを改造して, ユーザが昇順にソートするか,降順にソートするかを選べるようにした。 ソースコードはここに置いてある。 このプログラムは swap(), ascending(), descending(), qsort(), main() という 5 つの関数から成り立っている。 関数 qsort() は引数として, left 番目から right 番目までをソートするというソートの範囲, ソートすべき配列,の他に, 関数 ascending() あるいは descending() へのポインタを受け取る。 ユーザが 1 を入力したときには関数 ascending() へのポインタが qsort() へ渡され,2 を選択した時には descending() へのポインタが qsort() に渡される。

qsort() 関数の引数の中に

int (*comp_f)(int a, int b))

とある。 これは二つの int 型の引数を受け取って, int の値を返す関数へのポインタという意味である。 * 演算子は関数を囲んでいるカッコよりも優先順位が低い。 このため,*comp_f をカッコでくくっておく必要がある。 カッコでくくらないと

int *comp_f(int a, int b)

2 つの int 型変数を引数として受け取り, int 型へのポインタを返す関数という意味になる。

qsort() の中では,

            if ((*comp_f)(*(a+i), pivot_value)){

というように if 文の中で呼び出されている。

変数へのポインタを * で参照すれば, その変数の値にアクセスできるように, 関数へのポインタを * で参照すれば, その関数を呼び出すことができる。

次のサンプルコードは, 関数へのポインタの配列を使用した例である。 プログラムの先頭で3つの関数 funcA, funcB, funcC のプロトタイプが宣言されてる。これらの関数は, int 型の引数を一つとって,int を返す関数である。これらの関数は,main() の中で

	int (*func_array[3])(int x);
と宣言された,関数へのポインタの配列に格納される。
	func_array[0] = funcA;
	func_array[1] = &funcB;
	func_array[2] = &(funcC);

のそれぞれの代入は,すべて同じ意味である。 関数へのポインタの配列の宣言と代入とを同時に,

	int (*func_array[3])(int x) = {funcA, funcB, funcC};

としてもよい。これらの関数の呼び出しは,

	(*func_array[fn-1])(fn);

で行われている。

演習

上のソースコードを改造して,関数へのポインタの配列の宣言と代入を同時に行うように書き換えよ。

5 文字列,配列,ポインタ

5.1 文字列とポインタ

pointer-string.c
pointer-string-assignment.c

5.2 const 修飾子

const.c

5.3 文字列操作関数

string-assingnment.c

5.4 文字列の配列

jmark.c

5.5 ポインタ配列

pointer-array.c

5.6 main() 関数の引数

echo.c

5.7 メモリの動的割り当て


戻る

Shin-ichi ASAKAWA
asakawa@ieee.org