Cの関数ポインタについて

関数ポインタはちょっと厄介なのでメモ。

●関数へのポインタ

int func(double d);

って関数があると、関数funcへのポインタを格納するポインタ変数は、下記。

int (*func_p)(double);

つまり書式は以下。

戻り値 (関数へのポインタ変数)(引数型)

実際に使用例は下記。

int (*func_p)(double);
func_p = func;
func_p(0.5);

※ちなみに(*func_p)(0.5)としても問題なく動作する。
というより、変数だと下記のように使用すので、本来のポインタの性質からすればそのように記述すべき。

int a = 5;
int* a_p;
a_p = &a;
printf("a_p..%d\n",*a_p);

ただfunc_p(0.5)と記述できるのは、下記のような仕様のためらしい。
(1)関数は、式の中では「関数へのポインタ」に自動的に変換される。
ただし、アドレス演算子&のオペランドであるときと、sizeof演算子オペランドであるときは例外。
(2)関数呼び出しの演算子()は、「関数」ではなく、「関数へのポインタ」をオペランドとする。

●関数へのポインタ配列

下記3つの関数があるとする。

int func0(double d);
int func1(double d);
int func2(double d);

関数の配列は、下記のように宣言できる。

int (*func_table[])(double) = {
func0,
func1,
func2
};

使用する際は、下記のように使う。

func_table[i](0.5);

●所感
引数によって異なる処理をする、ポリモーフィズム的な振る舞いができる。
注意点としては、引数の型が同じでないといけない点。

※引数をvoid*とかにすれば、いろんな引数に対応できるのかもしれない。
 使用する際はキャストして使う的な。

参考:C言語ポインタ完全制覇

C言語ポインタ完全制覇 (標準プログラマーズライブラリ)

C言語ポインタ完全制覇 (標準プログラマーズライブラリ)