ここでどうやって
関数ポイントを宣言するためのC構文は、使用法を反映することを目的としていました。次のような通常の関数宣言を考えます<math.h>
:
double round(double number);
ポイント変数を使用するには、タイプセーフティを使用してそれを割り当てることができます。
fp = round;
あなたはそれを宣言する必要があります fp
このようにポイント変数を次のように。
double (*fp)(double number);
そのため、あなたがしなければならないことは、関数の使い方を見て、その関数の名前をポインタ参照に置き換えて、にするround
ことだけ*fp
です。ただし、余分なカレンのセットが必要です。これは、少し厄介になると言う人もいます。
おそらく、これは関数のシグネチャさえも持たない元のCで以前は簡単でしたが、そこに戻らないようにしましょう。
特に厄介なのは、引数として受け取る関数、関数へのポインターを返す関数、またはその両方を宣言する方法を見つけることです。
機能がある場合:
void myhandler(int signo);
次のようにしてシグナル関数(3)に渡すことができます:
signal(SIGHUP, myhandler);
または、古いハンドラーを保持する場合は、
old_handler = signal(SIGHUP, new_handler);
とても簡単です。非常に簡単なこと-また、きれいでも簡単でもないことは、宣言を正しくすることです。
signal(int signo, ???)
さて、あなたはあなたの関数宣言に戻り、ポイントリファレンスの名前を交換するだけです:
signal(int sendsig, void (*hisfunc)(int gotsig));
宣言していないためgotsig
、省略すると読みやすくなる場合があります。
signal(int sendsig, void (*hisfunc)(int));
またはそうでないかもしれません。:(
ただし、以下のようにsignal(3)も古いハンドラーを返すため、それでは十分ではありません。
old_handler = signal(SIGHUP, new_handler);
したがって、これらすべてを宣言する方法を理解する必要があります。
void (*old_handler)(int gotsig);
割り当てる変数には十分です。gotsig
ここで実際に宣言しているのではないことに注意してくださいold_handler
。これで本当に十分です:
void (*old_handler)(int);
これにより、signal(3)の正しい定義が得られます。
void (*signal(int signo, void (*handler)(int)))(int);
レスキューへのTypedef
この時までに、誰もがそれが混乱であることに同意すると思う。抽象化に名前を付ける方が良い場合があります。しばしば、本当に。これにより、次のtypedef
ことが理解しやすくなります。
typedef void (*sig_t) (int);
独自のハンドラー変数は
sig_t old_handler, new_handler;
そしてsignal(3)の宣言はちょうど
sig_t signal(int signo, sig_t handler);
これは突然理解できます。*を削除すると、混乱を招く括弧も削除されます(そして、かっこは常に物事を理解しやすくします-ハァッ!)。あなたの使用法は同じです:
old_handler = signal(SIGHUP, new_handler);
しかし、今、あなたはの宣言を理解する機会を持っているold_handler
、new_handler
とさえsignal
あなたが最初にそれらまたはそれらを記述する必要が発生したとき。
結論
非常に少数のCプログラマーが、参考資料を参照することなくこれらの事柄について正しい宣言を独力で考案できることがわかった。
カーネルとデバイスドライバーの仕事をしている人々へのインタビューの質問でこの質問があったことがあるからです。:)確かに、ホワイトボードでクラッシュして燃えたため、そのようにして多くの候補者を失いました。しかし、この分野での以前の経験はあるが、実際に仕事をすることができなかったと主張する人々を雇うことも避けました。
しかし、この広範囲にわたる困難のため、これを使用するために平均値の3シグマ以上に座っているトリプルアルファオタクプログラマーである必要がなくなったすべての宣言を実行する方法を持つことは、おそらく賢明なだけでなく、実際に合理的です。快適に。
f :: (Int -> Int -> Int) -> Int -> Int