1.( *(void(*) ( )) 0)( )
int main()
{
(*(void(*)())0)();
//调用0地址处的函数
//该函数无参,返回类型是void
//1. void(*)()----函数指针类型
//2.(void(*)())0----对0进行强制类型转换,被解释为一个函数地址
//3.*(void(*)())0----对0地址进行了解引用操作
//4.(*(void(*)())0)()----调用0地址处的函数
//出自《c陷阱和缺陷》
return 0;
}
首先观察突破口,这行代码里有一个0,把0前面的括号进行组合
得到(void(*)( )),最外面的括号显然是使0进行的强制类型转换,所以可以把最外面的括号去掉
得到void(*)( ),咋一看好怪呀,如果加入一点内容,变为void(*pf)(int),这个就是一个函数指针,指向参数为int,返回类型为void的函数,所以void(*)( )就是函数指针类型
(void(*)( ))0,就是对0强制类型转换为一个函数的地址
*(void(*)( ))0,对0地址进行了解引用操作
(*(void(*)( ))0) (),调用函数是 函数名(),函数指针指向一个函数,解引用后就是那个函数,所以这个代码是调用0地址处的函数
2.void(* signal(int, void(*)(int)))(int)
int main()
{
void(*signal(int, void(*)(int)))(int);
//1.signal和()先结合,说明signal是函数名
//2.signal函数的第一个参数的类型是int,第二个参数的类型是函数指针
//该函数指针,指向第一个参数为int,返回类型是void的函数
//3.signal函数的返回类型也是一个函数指针
//该函数指针,指向一个参数为int,返回类型是void的函数
//signal是一个函数声明
//typedef-对类型进行重定义
typedef void(*pfun_t)(int);//对void(*)(int)的函数指针类型重命名为pfun_t
//typedef unsigned int uint;
pfun_t signal(int, pfun_t); //void(*signal(int, void(*)(int)))(int) 完全等价
return 0;
}
首先,我们一看都是int,void这些,但其中有一个不一样,是signal,我们就从这里开始观察
signal先和其后面的括号进行结合,signal就是函数名,将其取出,signal(int,void(*)(int)),到这的时候我一眼就看见一个和我上面讲的那个几乎一样的,取出来,void(*)(int),这个不就是一个函数指针吗
所以signal函数的第一个参数的类型是int,第二个参数的类型是函数指针,指向参数类型为int,返回类型为void的函数
得到void(*)(int),本身就是一个函数指针类型,一眼就可以看出来
void(*signal(int, void(*)(int)))(int),所以函数signal的返回类型是一个函数指针,指向一个参数为int,返回类型为void的函数
我们可以抽象为void(*)(int) signal (int,void(*)(int))
但代码里面不支持
其实在代码里也有方法
我们可以使用typedef,也就是对类型进行重定义
很简单的,typedef void(*pfun_t)(int)
对void(*)(int)的函数指针类型重命名为pfun_t
pfun_t signal(int, pfun_t)与void(*signal(int, void(*)(int)))(int) 完全等价
也就是返回类型是这个函数指针,第二个参数类型也是函数指针