mfc从入门到放弃 01
typedef的用法总结
1,定义一种类型别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。
typedef char* PCHAR
PCHAR pa, pb; // 定义了两个指针
2,用在旧的代码中,帮助struct。以前的代码中,声明struct新对象,必须要带上struct,
即形式为:struct结构名对象名,如:
strcut tagPOINT1{
int x;
int y;
};
struct tagPOINT1 p1;
typedef struct tagPOINT {
int x;
int y;
}POINT;
POINT p1;// 这样就比原来的少写了一个struct,比较省事。
3,用typedef来定义与平台无关的类型。
//ps:现在好像不怎么用这个了
4,为复杂的神明定义一个新的简单的别名。方法是:在原来的声明里住不用别名替换一部分复杂声明,如此循环,
把带变量名的部分留到最后替换,得到的就是原声明的最简化版。
原声明:void (*b[10])(void(*)());
『
关于void (*b[10]) (void (*)());的讲解 ps:老实说我第一眼看见这行代码也是懵逼了。
在c和c++中,构造函数这类声明表达式只有一条简单的规则:按照使用的方式来声明。
c变量的声明都是由两部分组成的:类型,以及一组类似表达式的声明符。声明符类似于表达式,对它求值应该
返回一个声明中给定类型的结果。
例如,我们来看一个简单的声明:
float f;
这里f就是声明符,对其求值,应该的到一个float型的数值。
然后看括号的作用,比如:
float((f));
很简单,这个声明的含义就是,((f))的类型为浮点类型。因为括号和f之间没有其他的修饰了,所以,
我们可以推知,f也是浮点型。
在来看稍微复杂点的:
float f();
我们注意到有一个()表达式出现,这个声明符的含义是一个函数。所以这个声明的含义就是,f()的求值
结果是一个浮点数,也就是说,f是个返回值为浮点数的函数。
然后:
float *f();
这个就是表示*f()是个浮点表达式,而()的结合优先级高于*,所以,*f()也就是*(f()),f是个函数,返回值
是个指针,这个指针指向一个浮点数。
如果是:flaot (*f)(); 这时,f就不是和()结合而成为一个函数名,而是和*结合成为一个指针名,这个指针,
是指向函数入口的函数指针,而这个函数,返回值是浮点数。
现在我们知道怎么声明一个指定类型的变量了。在这个生命表达式中,把变量名,和声明末尾的分号去掉
剩余的部分用一个括号整个括起来,这样就得到了这个变量的类型声明了,比如:
float (*f)();
这个表示f是一个指向返回值为浮点型的函数指针。而我们把f这个变量名,和最后的;号去掉,就得到:
(flaot(*)())
这个就表示,这个表达式是一个类型,即“指向返回值为浮点型的函数的指针”。如果用这个类型去修饰
一个变量名,我们就叫它类型转换符。
现在有了这些储备知识,我们可以回头看标题的生命到底是什么意思了:
void (*b[10])(void(*)());
首先,表示的后半部分被两个()分割开了,我们分别分析他们。(*b[10]),其中出现了变量名b,很容易就知道,
b是一个有10个元素的数组,每个元素都是一个指针。
然后,看(void(*)()),其中没有出现变量名,所以它代表了一个类型,即“指向返回值为void型的函数的指针”,
而我们知道,C语法中,类型修饰符是必须出现在变量名的左边的,而在整个表达式中这个类型符是在变量名b的右边,
所以,(void(*)())最外层的这个(),表示了定义了一个函数,这个函数有一个参数,就是一个指针,具体来说,就是
“指向返回值为void型的函数的指针”。
这样就清楚了,b数组里,每一个指针元素,都是一个函数指针,这个函数有一个参数,这个参数是一个函数
指针。整个表达式最左边的void,则定义了b数组中函数指针所指向的返回值类型。
ps:事实的真相:这行代码就是TM逗你玩。。。
』
typedef void (*pFunParam)();
即表示,类型pFunParam,是一个函数指针。
然后,针对整个表达式声明一个类型:
typedef void (*pFun)(pFunParam);
即表示,类型pFun,是一个函数指针。此函数的参数类型为pFunParam。
最后,进行变量的生命:
pFun b[10];
编译器在进行代码扫描时是从左向右的,而我们在解读这个表达式的时候,从右向左的方法会更容易些。