signal函数:void (*signal(int,void(*)(int)))(int); 

2008-04-11 15:26:02



signal函数:void (*signal(int,void(*)(int)))(int)


#include <signal.h>
void (*signal (int sig, void (*func)(int)))(int);


That is to say, ​​signal​​​ is a function that returns a pointer to another function. This second function takes a single int argument and returns ​​void​​​. The second argument to ​​signal​​​ is similarly a pointer to a function returning ​​void​​​ which takes an ​​int​​ argument.





这个例子来自《C陷阱与缺陷》……


signal函数是著名的信号函数,但是它的定义却非常的复杂……


任何C变量,都是由“类型”+“表达式”组成,它表示,对“表达式”求值,返回的类型,是声明给定的“类型”的值,如




 

CODE:

int a;

也就是对表达式a求值,是一个int类型;


同样地,




 

CODE:

int func();

这个声明的含义是,对表达式func()求值结果是一个int类型,也就是说,func是一个返回值是int类型的函数。


进一步,




 

CODE:

int *a;

也就是,*a是一个整型变量,那a当然就是一个指针,一个指向整型类型变量的指针;


那么,




 

CODE:

int *func();

同样地,因为()的优先级高于*,所以func是一个函数,它返回一个整型变量指向整型变量的指针;


进一步地,




 

CODE:

int (*func)();

这一回*被括号括了起来,因为*被先执行,所以,func自然地是一个指针,它指向的类型是一个函数

,即func是一个指向函数的指针,

并且,这个函数,返回一个整型变量。


另一个要讨论的问题是,如何得到一个类型指定的类型转换符,比如:

int a;

float b;

要强b转换为int类型,需要把

int a;

中的变量名去掉,然后把末尾的;去掉,再把剩余的部份用括号括起来,即:

(int)

所以,以下表达式:

int (*func)();

如果我们要得到对应的函数指针的类型转换符,则把func去掉,再把;去掉,再用括号

把剩余的部份括起来,即:




 

CODE:

(int (*)())

表示一个“指向返回值为整型类型的函数的指针”的类型转换符。


那么,如果要将常数0,转换为一个函数指针,且这个函数返回值类型为void类型,应该如何表示呢?

根据上面所说,

(void (*)())

这个也就不用再解释,那么,要强制类型转换也很简单:

(void (*)())0

现在,它已经是一个函数指针了,把它简写为fp:

#define fp (void (*)())0

要调用这个函数指针,很简单,

(*fp)()

当然,fp是一个函数指针,这样的调用形式,可以简写为

fp()

,当然,这仅仅是简写……

所以,(*fp)(),把fp这个宏展开:

就是




 

CODE:

(*(void (*)())0)()

这么复杂的东东,其实很简单,就是先为常数0进行类型转换,转换为一个“指向返回类型为void的函数指针”,然后

再调用它。


用typedef来简化(*(void (*)())0)():




 

CODE:

typedef void (*funcptr)();

(*(funcptr)0)();

著名的signal函数的声明,就是这样啦:




 

CODE:

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

同样地,用typedef可以简化它:




 

CODE:

typedef void (*HANDLER)(int);

HANDLER signal(int,HANDLER);

这已经是我们习惯看到的形式了。

------------------越是喧嚣的世界,越需要宁静的思考------------------ 合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。 积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里;不积小流,无以成江海。骐骥一跃,不能十步;驽马十驾,功在不舍。锲而舍之,朽木不折;锲而不舍,金石可镂。蚓无爪牙之利,筋骨之强,上食埃土,下饮黄泉,用心一也。蟹六跪而二螯,非蛇鳝之穴无可寄托者,用心躁也。