不,C 函数声明/原型不能有多个标识符。请参考 cplusplus.com 上 signal 的参考页面和示例代码:http://www.cplusplus.com/reference/csignal/signal/。
在此声明中:
void (*signal(int sig, void (*func)(int)))(int);
我们声明了一个名为signal 的函数,它返回一个指向的函数,该函数返回void 并接受一个int——即:一个指向 一个这样的函数:
void func(int);
signal 函数的输入是第一个,int,第二个,一个指向函数的指针,该函数返回一个 void 并接受一个 int--再次,一个 指向 像上面的func 这样的函数。现在,在 C 语言中,当声明一个返回指向函数的指针并接受指向函数的指针的函数时,它看起来都像 goobly-ga-gook-looking(乱码和令人困惑的外观),这就是为什么我们最初都会感到困惑(一次又一次地)查看像signal这样的函数声明。在 C 中定义像 signal 这样的函数的几个更清晰的方法,使这一切都变得一目了然,就像这样,相反,这两种方法都与 goobly-gook-looking 相同:
// 1. typedef a function--call it `func_t` for "func type"
typedef void func_t(int);
// 2. Use the typedef above to define `signal`
func_t* signal(int sig, func_t* fp); // Ah, now this makes sense!
或
// 1. typedef a *pointer to* a function--call it `func_p` for "pointer to a func type"
typedef void (*func_p)(int);
// 2. Use the typedef above to define `signal`
func_p signal(int sig, func_p fp); // Ah, now this makes sense too!
请记住,函数中的每个输入参数类型 声明 在 C 中是无关紧要的,甚至不必在头文件和源文件之间进行匹配。
例如:
my_module.h:
// Any of these 3 prototypes are equivalent, valid, and identical
// (although using sensible names which match between the header &
// source files is most clear and helpful to the reader!):
func_p signal(int sig, func_p fp);
func_p signal(int signal, func_p whatsupdude);
func_p signal(int, func_p);
my_module.c:
func_p signal(int sig, func_p fp)
{
// define the function here
}
现在,我最初是如何弄清楚这一切的?
答:我看了the example code from cplusplus.com。它帮助 TON 澄清了这一切,您可以看到 signal 的返回值是如何分配给 prev_handler 的,它是一个指向函数的指针,您可以看到 my_handler 是如何定义为一个函数,作为第二个参数传递给signal!对于踢球,我可能还应该提到这两行是相同的,并且都是完全有效的:
prev_handler = signal (SIGINT, my_handler);
prev_handler = signal (SIGINT, &my_handler);
这是因为如果你将一个函数作为参数传入,编译器就知道无论如何都要取它的地址。
Cplusplus example code:
/* signal example */
#include <stdio.h> /* printf */
#include <signal.h> /* signal, raise, sig_atomic_t */
sig_atomic_t signaled = 0;
void my_handler (int param)
{
signaled = 1;
}
int main ()
{
void (*prev_handler)(int);
prev_handler = signal (SIGINT, my_handler);
/* ... */
raise(SIGINT);
/* ... */
printf ("signaled is %d.\n",signaled);
return 0;
}
参考资料:
- 提醒一下如何对函数和函数指针进行类型定义,因为这会让几乎每个人都感到困惑,并且需要不时重新验证:http://www.iso-9899.info/wiki/Typedef_Function_Type