関数へのポインタとは, 関数の実体(コンピュータのメモリ上のどこかに存在する) 関数の先頭アドレスを値として持つポインタのことである。 配列,例えば 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);
で行われている。
pointer-string.c
pointer-string-assignment.c