なるべく外側から読みとくといいよ的なことを以前どこかで見たんだけど忘れてしまったので,メモ程度に残しておく.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便利.関数ポインタをたくさん使うなら必須だと思う.