您的位置:首页 > 其它

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

2013-01-25 14:44 621 查看
原文: http://blog.chinaunix.net/uid-20178794-id-1972862.html
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);

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

===============================

c语言,理解声明的“左右法则”
http://wenku.baidu.com/view/3891df0e844769eae009ed40.html http://www.oschina.net/question/171512_63027
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: