(void (*)())0 解析步骤:
1、fp是一个指向返回值为void类型的函数的指针:void (*fp)();调用方式简写为:(*fp)();
2、制作其对应的类型转换符:void (*)()
3、存储位置为0的转换为一个指向返回值为void类型的函数的指针:(void (*)())0
4、用上式代替fp,从而实现调用存储位置为0的子例程:(*(void(*)())0)();
5、利用typedef简化:typedef void (*funcptr)(); (*(funcptr)0)();
下面将相关基础知识进行介绍,其中参考了网上一些文章,名单不再列出,谢谢各位大虾的贡献: 1、c语言的声明 2、类型转换符的制作 3、signal函数分析 4、typedef用法 5、const用法 6、typedef的好处
1、c语言的声明
声明由两部分组成:类型以及声明符:
float f,g;
float ((f));//对其求值时,((f))的类型为浮点型,可以推知,f也是浮点型
float *g(),(*h)();//g是函数,该函数的返回类型为指向浮点数的指针
//h是个指针,且是一个函数指针,该指针指向函数返回值,该返回值是一个float型
(*fp)()简写为fp()//函数调用方式,其中fp为函数指针
*((*fp)())简写为*fp()//函数返回值为某个类型的指针
2、类型转换符制作:
类型转换符制作:1、去掉声明中的变量名、分号;2、将剩余部分用括号"封装"起来
float (*h)(); --> (float (*)())//指向返回值为float型的函数指针的类型转换符
(*0)();//返回值为void类型的函数指针
如果fp是一个指向返回值为void类型的函数的指针,那么(*fp)()的值为void,fp的声明如下:
void (*fp)();
因此可以用下式完成调用存储位置为0的子例程:
void (*fp)();
(*fp)();
这种写法的代价是多声明了一个哑变量,我们常将0转型为“指向返回值为void的函数的指针”:
(void (*)())0
用上式代替fp,从而得到:(*(void(*)())0)();
typedef void (*funcptr)();
(*(funcptr)0)();
3、signal函数
signal函数接受两个参数:信号类型的整型值、指向用户提供的信号处理函数指针
用户提供的信号处理函数返回值类型为:void
signal的返回值类型:指向调用前的用户定义信号处理函数的指针
下面分析signal函数在signal.h中是如何声明的
1、用户定义信号处理函数:void sigfunc(int n){/*特定信号处理部分*/}
2、sigfunc声明:void sigfunc(int);
3、假设sfp指向sigfunc函数,sigfunc函数声明:void (*sfp)(int);
4、假设sig为一整数,则 (*sfp)(sig)返回值为void类型
5、sfp与signal返回值类型相同,故声明signal函数:void (*signal(something))(int);
//something为signal的参数类型
//过程分析:传递一个适当的参数调用signal;对signal的返回值解引用;传递一个参数调用解引用后
//得到的函数;得到返回值为void型
//signal函数返回值是一个指向返回值为void类型的函数的指针
6、signal其中参数为:int 、 void (*)(int),故signal函数:void (*signal(int,void (*)(int)))(int);
7、用typedef简化: typedef void (*HANDLER)(int); HANDER signal(int,HANDER);
4、typedef用法
例1:
int* (*a[5])(int, char*);
typedef int* (*PF)(int, char*);//PF是一个类型别名
PF a[5];//跟int* (*a[5])(int, char*);的效果一样!
//很多初学者只知道typedef char* p