関数ポインタの読み解き方

なるべく外側から読みとくといいよ的なことを以前どこかで見たんだけど忘れてしまったので,メモ程度に残しておく.signal関数を例にしてみる.


これがsignal関数のプロトタイプ宣言文.何のこっちゃという感じ.

void (*signal(int sig, void (*func)(int)))(int);


というわけで早速外側から解読開始.


intを引数に取り戻り値がvoidの関数へのポインタ型

void (*..................................)(int)

signalという名前の関数

       signal(..........................)

sigという名前のint型の仮引数

              int sig, .................

intを引数に取り戻り値がvoidの関数へのポインタ型

                       void (*....)(int)

funcという名前の仮引数

                              func


以上より,

void (*signal(int sig, void (*func)(int)))(int);

は,『引数がint型と「intを引数に取り戻り値がvoidの関数へのポインタ型」,戻り値が「intを引数に取り戻り値がvoidの関数へのポインタ型」関数signalの宣言』であることが分かる(よね?).


ちなみに,上の記述中に「intを引数に取り戻り値がvoidの関数へのポインタ型」が二回出てきている.これをtypedefするとsignal関数の宣言が以下のように簡単になる.

typedef void (*sig_t)(int);
sig_t signal(int sig, sig_t func);

typedef便利.関数ポインタをたくさん使うなら必須だと思う.