程序如下:
(*(void(*)())0);
如果你看完这条语句还没有蒙,那你已经完全没必要继续在这个贴上浪费时间了,可以直接关掉这个页面,如果感觉有点蒙,可以选择继续~~
首先需要说明几个概念:
1.函数的调用:函数的调用可以通过函数名调用(这个使用的最普遍),也可以通过函数指针调用(即指向函数的指针变量调用)。如
int a,b,c;
int max(int,int);
int (*p)(int,int);
p=max;
如果要调用max函数,可以使用c=max(a,b);也可以使用c=(*p)(a,b);
通过max(a,b)就调用了max函数,这是为什么呢?这不过是一种简写,这样写你看有没有感觉:(*max)(a,b); max是什么,*max是什么?对于这一点函数和数组是一样的,数组名表示数组的首地址,函数名也就表示该函数的入口地址,*是什么,指针运算符,来取地址间接访问,*max就表示取max函数的入口地址,也即调用执行这个函数了,为什么在这儿加括号?因为函数运算符()的优先级高于单目运算符*,如果不加,那么它就等同于*(max(a,b)),这个是什么意思?交给你吧,我们继续~
2.类型转换符
如果我们知道了如何声明一个给定类型的变量,那么就很容易得到该类型的类型转换符:只需要将声明中的变量名和声明末尾的分号去掉,再将剩余的部分用一个括号封装起来就行了。比如:
int i;
float j;
(int)j;
把变量名i和末尾的分号去掉,再加个括号就是(int),就是把浮点型的j强制转换为int型;再如void(*h)();定义了一个指向返回值为空的函数的指针,(void(*)())就是“指向返回值为空的函数的指针”的类型转换符。
到了这里,我们就可以写个类型转换符,将0转换为指向无返回值(或返回值为空)的函数的指针:
首先将0变为一个函数的入口地址,可以写成(void(*)())0,这个表达式就是将0强制转换为指向无返回值的函数的指针,好了,根据1中所述的函数调用方法我们可以尝试调用这个函数指针,(*(void(*)())0)();这条语句也就是执行入口地址为0的函数了,这也正是上面所讲的复位语句。
——详见《C陷阱与缺陷》之“语法缺陷”