头痛,迷一样的东西
(*(void(*)())0)();
这个是什么?
这也太变态了。
[解决办法]
.(*void(*)()0)();此语句可用于主机上电,硬件调用首地址为零位置的代码,以下分析此语句:
(i) float *g(),(*h)();*g()表示*(g()):g是一个函数,该函数的返回值类型为指向浮点数的指针,h是一个函数指针,所指向函数的返回值为 浮点类型。
(ii)由(i)可知道*h指向该指针所指向的函数,那么(*h)()就是调用该函数。(ANSI C标准也允许这样调用h();)
(iii)由(i)可知道float (*h)()是对一个float类型的函数指针的声明,那么void (*h)()便是对void类型函数指针的声明,则(void (*)())0便 是对常数0进行类型转换,转换为 "指向返回值为void的函数的指针 "类型,用(void (*)())0来替换式子h()中的h,则得到(*void(*)()0)()
(iv)用tupedef更能清楚表达:typedef void (*fun)();
(*(fun)0)();
[解决办法]
x=(void(*)())0
这个是把 数值0 强制转换成 一个函数指针,即函数的入口地址
(*x)() 这个就是执行x代码了,
也就是执行地址0处的代码 ····
[解决办法]
2.1 理解声明
我曾经和一些人聊过天,他们那时在书写在一个小型的微处理器上单机运行的C程序。当这台机器的开关打开的时候,硬件会调用地址为0处的子程序。
为了模仿电源打开的情形,我们要设计一条C语句来显式地调用这个子程序。经过一些思考,我们写出了下面的语句:
(*(void(*)())0)();
这样的表达式会令C程序员心惊胆战。但是,并不需要这样,因为他们可以在一个简单的规则的帮助下很容易地构造它:以你使用的方式声明它。
每个C变量声明都具有两个部分:一个类型和一组具有特定格式的期望用来对该类型求值的表达式。最简单的表达式就是一个变量:
float f, g;
说明表达式f和g——在求值的时候——具有类型float。由于待求值的时表达式,因此可以自由地使用圆括号:
float ((f));
这表示((f))求值为float并且因此,通过推断,f也是一个float。
同样的逻辑用在函数和指针类型。例如:
float ff();
表示表达式ff()是一个float,因此ff是一个返回一个float的函数。类似地,
float *pf;
表示*pf是一个float并且因此pf是一个指向一个float的指针。
这些形式的组合声明对表达式是一样的。因此,
float *g(), (*h)();
表示*g()和(*h)()都是float表达式。由于()比*绑定得更紧密,*g()和*(g())表示同样的东西:g是一个返回指float指针的函数,而h是一个指向返回float的函数的指针。
当我们知道如何声明一个给定类型的变量以后,就能够很容易地写出一个类型的模型(cast):只要删除变量名和分号并将所有的东西包围在一对圆括号中即可。因此,由于
float *g();
声明g是一个返回float指针的函数,所以(float *())就是它的模型。
有了这些知识的武装,我们现在可以准备解决(*(void(*)())0)()了。 我们可以将它分为两个部分进行分析。首先,假设我们有一个变量fp,它包含了一个函数指针,并且我们希望调用fp所指向的函数。可以这样写:
(*fp)();
如果fp是一个指向函数的指针,则*fp就是函数本身,因此(*fp)()是调用它的一种方法。(*fp)中的括号是必须的,否则这个表达式将会被分析为*(fp())。我们现在要找一个适当的表达式来替换fp。
这个问题就是我们的第二步分析。如果C可以读入并理解类型,我们可以写:
(*0)();
但这样并不行,因为*运算符要求必须有一个指针作为他的操作数。另外,这个操作数必须是一个指向函数的指针,以保证*的结果可以被调用。因此,我们需要将0转换为一个可以描述“指向一个返回void的函数的指针”的类型。
如果fp是一个指向返回void的函数的指针,则(*fp)()是一个void值,并且它的声明将会是这样的:
void (*fp)();
因此,我们需要写:
void (*fp)();
(*fp)();
来声明一个哑变量。一旦我们知道了如何声明该变量,我们也就知道了如何将一个常数转换为该类型:只要从变量的声明中去掉名字即可。因此,我们像下面这样将0转换为一个“指向返回void的函数的指针”:
(void(*)())0
接下来,我们用(void(*)())0来替换fp:
(*(void(*)())0)();
结尾处的分号用于将这个表达式转换为一个语句。
在这里,我们就解决了这个问题时没有使用typedef声明。通过使用它,我们可以更清晰地解决这个问题:
typedef void (*funcptr)();
(*(funcptr)0)();
C陷阱与缺陷http://www.upsdn.net/html/2006-10/723.html