程序设计错误,或者你无法按某个算法写出程序,实际上反应的是程序员与该程序与算法的“心智模式”不匹配,或者说,你的心智模式无法包容与理解下该程序算法所包含的思想(如果你不了解心智模式,可以到这里看看:心智模式专题)。
比如下面的一个语句:
( *( void(*)())0)();
这是一个什么东西呢?
像这样的表达式恐怕会令大部分C/C++程序员的内心都“不寒而栗”吧。这是一个当计算机启动时,硬件将调用首地址为0位置的子例程。
看不懂也不用担心,这个知识目前处于你学习的“恐慌区”,接下来我们慢慢将它变成你学习的“学习区”,再熟练下,它就会简单成为你学习的“舒适区”了。学习就是这样,不断把“恐慌区”的知识转化成“学习区”,再转化成“舒适区”,你转化得越多,你就越是别人眼里的“大牛”。
从最简单开始,慢慢理解与深入。
最简单的声明
任何C变量的声明都由两部分组成:类型以及一组类似表达式的声明符(declarator)。声明符从表面上看与表达式有些类似,对它求值应该返回一个声明中给定类型的结果。最简单的声明符就是单个变量,如:
float f , g ;
这个声明的含义是:当对其求值时,表达式f和g的类型为浮点数类型(float)。这个很简单,大家都懂。
因为声明符与表达式的相似,所以我们也可以在声明符中任意使用括号:
float ((f));
这个声明的含义是:当对其求值时,((f))的类型为浮点类型,由此可以推知,f也是浮点类型。一个简单的程序例子:
#include "stdio.h"
int main()
{
float ((f)) = 0.5;
printf("%.2f", f);
}
同样的逻辑也适用于函数和指针类型的声明,例如:
float ff();
这个声明的含义是:表达式ff()求值结果是一个浮点数,也就是说,ff是一个返回值为浮点类型的函数。类似地,
float *pf;
这个声明的含义是*pf是一个浮点数,也就是说,pf是一个指向浮点数的指针。
以上这些形式在声明中还可以组合起来,就像在表达式中进行组合一样。因此,
float *g(), (*h)();
表示*g()与(*h)()是浮点表达式。因为()结合优先级高于*,*g()也就是*(g()):g是一个函数,该函数的返回值类型为指向浮点数的指针。同理,可以得出h是一个函数指针,h所指向函数的返回值为浮点类型。
从声明到类型转换符
一旦我们知道了如何声明一个给定类型的变量,那么该类型的类型转换符就很容易得到了:只需要把声明中的变量名和声明末尾的分号去掉,再将剩余的部分用一个括号整个“封装”起来即可。例如,因为下面的声明:
float (*h)();
表示h是一个指向返回值为浮点类型的函数的指针,因此,
(float (*)())
表示一个“指向返回值为浮点类型的函数的指针”的类型转换符。
拥有了这些预备知识,我们在下一篇就可以分两步来分析表达式 (*(void(*)())0)() 。
网友评论已有0条评论, 我也要评论