3

UNIXでシグナル処理を勉強していて、これに出くわしました

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

このプロトタイプと、これが関数へのポインターを返す方法を理解していません。

私もこの答えを読みました: Cの関数ポインタはどのように機能しますか? しかし、それは私には明らかではありません。

関数ポインターを返すはずですが、戻り値の型を別の関数ポインターとして指定する場所がわかりません。
私が見る方法は(*foo(int n))、関数定義で使用すると、この関数の戻り値の型がfoo(int n)関数ポインターになるということです.これは正しいですか?
これにはもっと簡単な例がありますか?

4

3 に答える 3

3

それでは、関数ポインタの宣言方法を見てみましょう。

return-type (*function-name)(parameter-list);

投稿した宣言では、2 つの関数ポインター型が使用されています。signal1 つ目は、プロトタイプに一致する関数に渡されるパラメーターです。

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

その関数ポインター型の名前を に変更しhandler、独自の宣言を与えましょう。

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

これで、残りの宣言を分解できます。「内側」の部分は実際の関数宣言です。

...signal(int sig, handler func)...

そして、「外側」は、それが返す関数ポインタを記述します:

void (...)(int);

これは、私たちの型と同じ関数ポインタ型handlerでもあるので、そのtypedef場所で、次のsignalように関数を再宣言することができます:

handler signal(int sig, handler func);

(はるかにきれいです。)

于 2013-08-12T00:22:41.450 に答える
1

関数ポインターの定義を単純化するために使用typedefできます。これは、長くて複雑な定義を理解するのに役立ちます。

#include <stdio.h>
typedef void (*func)(int);
typedef void (*rtype)(int);

void myfunc(int a)
{
    printf("A is %d\n", a);
}

// thus signal can be defined as this
// exactly the same as in your question
rtype signal(int a, func handler)
{
    return myfunc;
}

int main()
{
    signal(0, 0)(12);
    return 0;
}

上記のコードは次を出力する必要がありますA is 12

希望が役立ちます!

于 2013-08-12T00:58:22.903 に答える
1
void (*signal(stuff))(int)

引数として int を取り、void を返す関数へのポインタを返すものとして signal を宣言します。スタッフはシグナルに引数を与えます。この場合は

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

つまり、関数 signal の最初の引数は int で、2 番目の引数は int を引数として取り、void を返す関数ポインタです。

編集:したがって、電話をかけた場合-たとえば、

void foo (int x) {
    return;
}
void *bar = (*signal)(0, &foo);

この場合、bar は int を取り、何も返さない関数へのポインターになり、次のように呼び出すことができます。

(*bar)(0);
于 2013-08-12T00:19:32.300 に答える