理解函数声明--signal函数的声明
1.显示调用首地址为0的例程:(*(void(*)())0)()
显示调用首地址为0的例程的表达式为:(*(void(*)())0)()
分两步分析:
- 假定变量fp是一个函数指针,调用方法如下:(*fp)();
因为fp是一个函数指针,那么*fp就是该指针指向的函数,所以(*fp)()就是调用该函数的方式。ANSI C标准允许程序员将上式简写为fp()。()的运算符高于*。
2.使用具体的函数指针替换fp,此处将0做类型强制转换,转换为函数指针,替换fp。
对一个常数进行类型转换,只需在变量声明中将变量名去掉即可。如果fp是一个指向返回值为void类型的函数的指针,那么(*fp)()的值为void,fp的声明如下:
void (*fp)();将变量名去掉,将0转换为"指向返回值为void的函数的指针"类型这样写:(void(*)())0
因此,可以用(void(*)())0替换fp,从而得到:
(*(void(*)())0)();
使用typedef声明更加便于理解。
typedef void(*funcptr)(); //相当于typedef void (*)() funcptr
((*funcptr)0)();
2.signal函数声明理解:void(*signal(int, void(*)(int)))(int)
从三个方面理解:返回值类型、函数指针以及参数。
signal函数的返回值类型是一个指向调用前的用户定义信号处理函数的指针,
假定特定信号处理函数的声明如下:
void sigfunc(int);
假定sfp为指向sigfunc的函数指针,则*sfp就代表了sigfunc函数,因此可以如下声明sfp:
void (*sfp)(int);
signal的参数列表是(int,sigfunc), 返回值是sigfunc,所以signal可以声明如下:
sigfunc signal(int, sigfunc)
替换sigfunc,即:void(*sfp)(int) signal(int, void(*sfp)(int))
去掉变量名,即:void (*)(int) signal(int, void(*)(int))
调顺序,即:void (*signal(int, void(*)(int)))(int)
使用typedef声明更加便于理解。
typedef void (*HANDLER) (int);
HANDLER signal (int, HANDLER);