最近我在阅读APUE,发现以下函数的定义:
void (*signal(int signo, void (*func)(int)))(int);
我感到困惑,我知道信号是指向函数的指针,而最后的(int)是它的参数。 我不知道(int signo,void (*func)(int))是什么意思。
最近我在阅读APUE,发现以下函数的定义:
void (*signal(int signo, void (*func)(int)))(int);
我感到困惑,我知道信号是指向函数的指针,而最后的(int)是它的参数。 我不知道(int signo,void (*func)(int))是什么意思。
()
和[]
会在一元运算符如*
之前绑定;因此,以下所有情况都是正确的:T *x[N] -- x is an N-element array of pointer to T
T (*x)[N] -- x is a pointer to an N-element array of T
T *f() -- f is a function returning a pointer to T
T (*f)() -- f is a pointer to a function returning T
signal -- signal
signal( ) -- is a function
signal( signo, ) -- with a parameter named signo
signal(int signo, ) -- of type int
signal(int signo, func ) -- and a parameter named func
signal(int signo, *func ) -- of type pointer
signal(int signo, (*func)( )) -- to a function
signal(int signo, (*func)(int)) -- taking an int parameter
signal(int signo, void (*func)(int)) -- and returning void
*signal(int signo, void (*func)(int)) -- returning a pointer
(*signal(int signo, void (*func)(int)))( ) -- to a function
(*signal(int signo, void (*func)(int)))(int) -- taking an int parameter
void (*signal(int signo, void (*func)(int)))(int); -- and returning void
signal
返回一个指向返回 void
的函数的指针。 signal
接受两个参数:一个整数和一个指向另一个返回 void
的函数的指针。signal
函数设置信号处理程序;第二个参数是在接收到信号时要执行的函数。返回当前信号处理程序(如果有)。例如,如果你想让你的程序处理中断信号(如来自 Ctrl-C 的信号):static int g_interruptFlag = 0;
void interruptHandler(int sig)
{
g_interruptFlag = 1;
}
int main(void)
{
...
/**
* Install the interrupt handler, saving the previous interrupt handler
*/
void (*oldInterruptHandler)(int) = signal(SIGINT, interruptHandler);
while (!g_interruptFlag)
{
// do something interesting until someone hits Ctrl-C
}
/**
* Restore the previous interrupt handler (not necessary for this particular
* example, but there may be cases where you want to swap out signal handlers
* after handling a specific condition)
*/
signal(SIGINT, oldInterruptHandler);
return 0;
}
编辑 我扩展了signal
的示例代码,希望更具有说明性。
void (*signal(int signo, void (*func)(int)))(int);
signal是一个函数,它接受一个整数和一个指向接受整数并返回void的函数的指针,并返回一个接受整数并返回void的函数指针。
typedef void(*funcPtr)(int)
那么我们就有
funcPtr signal(int signo, funcPtr func); //equivalent to the above
语法确实很奇怪,最好使用typedef来完成这样的操作。例如,如果你想声明一个函数,该函数接受一个int并返回一个指向带有char参数并返回double的函数的指针,那么将是:
double (*f(int))(char);
编辑:在一条评论中,读到了“哇哇哇”的留言后,我提供了另一个更加“哇哇”的示例:)
让我们声明一个函数,它需要:
1. 一个指向包含5个指向接受浮点数并返回双精度值的函数指针的数组的指针。
2. 一个指向包含3个指向4个整数数组的指针的数组的指针。
并且这个函数返回一个指向接受一个指向接受整数并返回一个指向接受浮点数并返回空指针的函数的指针,并返回无符号整数的函数指针。
typedef 解决方案如下:
typedef double (*f1ptr) (float);
typedef f1ptr (*arr1ptr)[5];
typedef int (*arr2ptr)[4];
typedef arr2ptr (*arr3ptr)[3];
typedef void(*f2Ptr)(float);
typedef f2ptr (*f3ptr)(int);
typedef unsigned int (*f4ptr) (f3ptr);
f4ptr TheFunction(arr1ptr arg1, arr3ptr arg2);
现在到了有趣的部分 :) 如果没有typedef,这将是:
unsigned int (*TheFunction( double (*(*)[5])(float), int(*(*)[3])[4]))( void(*(*)(int))(float))
我的天,我刚刚写下了那个? :)
如果您现在无法访问cdecl
,这里是输出结果:
$ cdecl
cdecl> explain void (*signal(int , void (*)(int)))(int);
declare signal as function (int, pointer to function (int) returning void) returning pointer to function (int) returning void
cdecl
。它会告诉你所有这些信息。我问:explain void (*signal(int, void (*)(int)))(int);
,它回答道:声明 signal 为函数 (int,指向返回 void 的函数指针 (int) 的指针) 的返回类型为指向返回 void 的函数指针 (int) 的指针
。 - Chris Lutz