2012-02-29 7 views
16

可能性の重複:
Cでこの複合宣言を読むにはどうすればよいですか?

what's the meaning of this piece of code? void (*signal(int sig, void (*func)(int)))(int);

I "はsignal.hに" ヘッダファイルから取得し、以下の宣言であるされている複雑な宣言を持っています。今

​​

、私はそれをどのように解析するのですか?として

信号は、int型の 'sig'と引数としてintを取る関数へのポインタである 'func'という2つの引数をとる関数であり、void型を返します。引数としてintをとり、voidを返す関数へのポインタを返します。

シグナルが機能するかどうかは問題ありませんか?

+0

しかし、これは私がhttp://www.joyofprogramming.com/Docs_ColumnArticles/36-JoP-Dec-09.pdfから混乱しているところです。 –

+0

'typedef int foo(void)':fooは関数へのポインタですしかし、 'foo x 'を使うことができるので、それをショートカットして関数と言うことができます。 x(); ' – Benoit

+0

@Benoitあなたはあなたの答えとしてそれを追加できますか? –

答えて

59

スタートと[]()バインド*前に、そう*a[]は、ポインタの配列であることを思い出して、あなたの方法を動作し、(*a)[]*f()がポインタを返す関数である、配列へのポインタである、と(*f)()関数へのポインタです:

 signal          -- signal 
     signal(      )   -- is a function 
     signal( sig,     )   -- with a parameter named sig 
     signal(int sig,     )   -- of type int 
     signal(int sig,  func  )   -- and a parameter named func 
     signal(int sig,  (*func) )   -- which is a pointer 
     signal(int sig,  (*func)( ))   -- to a function 
     signal(int sig,  (*func)(int))   --  taking an int parameter 
     signal(int sig, void (*func)(int))   --  and returning void 
     *signal(int sig, void (*func)(int))   -- returning a pointer 
    (*signal(int sig, void (*func)(int)))( ) -- to a function 
    (*signal(int sig, void (*func)(int)))(int) -- taking an int parameter 
void (*signal(int sig, void (*func)(int)))(int); -- and returning void 

signal仲間信号sigとシグナルハンドラ関数funcは、古いシグナルハンドラ関数へのポインタを返します。

void new_interrupt_handler(int sig) 
{ 
    ... // do something interesting with interrupt signal 
} 

int main(void) 
{ 
    void (*old_interrupt_handler)(int); 
    ... 
    /** 
    * Set up our new interrupt handler 
    */ 
    old_interrupt_handler = signal(SIGINT, new_interrupt_handler); 
    ... 
    /** 
    * Restore original interrupt handler 
    */ 
    signal(SIGINT, old_interrupt_handler); 
    ... 
} 
+4

+1非常に良い、ステップバイステップの説明。 – watbywbarif

+0

あなたの考えで@Johnに感謝しますが、ここに反対してシグナルを言う一部のユーザーは機能へのポインタです。 –

+0

@Amit - Aaronのケースでは、彼が 'cdecl'に与えた文字列はあなたの質問に書いたものではありません。 –

1

signalは、2つのパラメータをとり、パラメータとしてintをとり、voidを返す関数へのポインタを返す関数です。 signalがかかり

2つのパラメータは、int、パラメータとしてintを取り、voidを返す関数へのポインタです。

はい、あなたは説明と全体的なアイデアを持っています。 cdecl.orgを使用して

3

、あなたが入力

ため、ボイド

を返す関数へのポインタを返す関数(INT、空を返す)(int型の関数へのポインタ)として

宣言信号(int)を取得します

void (*signal(int, void(*)(int)))(int) 

これは、signalが機能であることを意味します。 signalを呼び出した結果は、関数void f(int)へのポインタになります。

説明:signal()呼び出しが新しいシグナルハンドラをインストールし、(あなたがしたい場合ので、あなたが後でそれを復元することができます)古いシグナルハンドラを返します。

+0

しかし私の文脈では違うのですか? –

+0

@Aaron - あなたはOPと同じ宣言を入力しませんでした。 –

+0

@JohnBode:そうです。一定。 –

1

いいえ、そうです。信号は2つの引数、INTと関数へのポインタをとり、関数へのポインタを返す

それは(IMO)より読みやすいと同様だ(func引数と同じ署名で):

typedef void (*sig_func)(int); 
sig_func signal(int sig, sig_func func); 
+0

GNUは 'sighandler_t'を呼び出し、libc4とlibc5は' SignalHandler'を呼び出し、glibcは 'sig_t'をBTWと呼んでいます。 ;) – Gandaro

+0

これはコードの記述方法です。あなたが "関数ポインタをパラメータとして取る関数への関数ポインタ"としてあまり知られていないものを宣言するときにtypedefを使用していないなら、あなたは悪く、おそらくかなり怪しいです。 – Lundin

0
void (*signal(int, void (*)(int)))(int); 

     signal(    )   // signal is a function 
       int, void (*)(int)   // the parameter types of the function: 
              // an int and a function pointer (take int, return void) 
void (*       )(int); // the return type of the function: 
              // a function pointer (take int, return void) 

//編集はJohnの答えを参照してください。

左端の識別子と
+0

シグナルがどのように関数へのポインタですか? –

+0

これはsignalがポインタを返す関数であることを示します。 –

+0

これは本当に混乱しています。答えのほとんどは、ポインタを返す関数を示し、あなたは異なっていると言います。 –

関連する問題