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);

在您发布的声明中,有两种函数指针类型在起作用。signal第一个是传递给与原型匹配的函数的参数:

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
void (*signal(stuff))(int)

将信号声明为返回一个指向以 int 作为参数并返回 void 的函数的指针。这些东西给出了信号的参数,在这种情况下是

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

也就是说,函数信号的第一个参数是一个 int,第二个参数是一个以 int 作为参数并返回 void 的函数指针。

编辑:因此,如果你打了一些电话——例如,

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

那么 bar 将是一个指向函数的指针,该函数采用 int 并且不返回任何内容,因此可以如下调用:

(*bar)(0);
于 2013-08-12T00:19:32.300 回答
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 回答