tyedef的用法

来源:互联网 发布:大卫罗兵逊生涯数据 编辑:程序博客网 时间:2024/06/05 07:49

在编程中使用typedef目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。

例如,你不用像下面这样重复定义有 81 个字符元素的数组:

 char line[81];char text[81];



只需这样定义,Line类型即代表了具有81个元素的字符数组,使用方法如下:

4 typedef char Line[81];Line text,line;getline(text);



同样,可以像下面这样隐藏指针语法:

 

typedef char* pstr; int mystrcmp(const pstr p1,const pstr p3);



用GNU的gcc和g++编译器,是会出现警告的,按照顺序,‘const pstr'被解释为‘char* const‘(一个指向char的指针常量),而事实上,const char*和char* const表达的并非同一意思(详见C++ Primer 第四版 P112)。

char * const cp : 定义一个指向字符的指针常数,即const指针,常量指针。


const char* p : 定义一个指向字符型常量的指针。


char const* p : 等同于const char* p。



上面讨论的 typedef 行为有点像 #define 宏,用其实际类型替代同义字。不同点是 typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。例如:

typedef int (*PF) (const char *, const char *);

这个声明引入了 PF 类型作为函数指针的同义字,该函数有两个 const char * 类型的参数以及一个 int 类型的返回值。如果要使用下列形式的函数声明,那么上述这个 typedef 是不可或缺的:

PF Register(PF pf);

Register() 的参数是一个 PF 类型的回调函数,返回某个函数的地址,其署名与先前注册的名字相同。做一次深呼吸。下面我展示一下如果不用 typedef,我们是如何实现这个声明的:

int (*Register (int (*pf)(const char *, const char *)))(const char *, const char *);



很少有程序员理解它是什么意思,更不用说这种费解的代码所带来的出错风险了。显然,这里使用 typedef 不是一种特权,而是一种必需。持怀疑态度的人可能会问:"OK,有人还会写这样的代码吗?",快速浏览一下揭示 signal()函数的头文件 ,一个有同样接口的函数。注意这里Register被定义为一个函数而不是函数指针,如果要定义为函数指针应该这样写:int (*(*Register) (int (*pf)(const char *, const char *))) (const char *, const char *);

typedef 和存储类关键字(storage class specifier)

这种说法是不是有点令人惊讶,typedef 就像 auto,extern,mutable,static,和 register 一样,是一个存储类关键字。这并不是说 typedef 会真正影响对象的存储特性;它只是说在语句构成上,typedef 声明看起来象 static,extern 等类型的变量声明。下面将带到第二个陷阱:

typedef register int FAST_COUNTER; // 错误

编译通不过。问题出在你不能在声明中有多个存储类关键字。因为符号 typedef 已经占据了存储类关键字的位置,在 typedef 声明中不能用 register(或任何其它存储类关键字)。


参考资料:http://baike.baidu.com/link?url=fDMjKVG-vR4U27jWQvQKzZ3JszMK0cdWaF4309Y8tFNxEazA5NwFdLoTsqq2CO1YRa7KZgfH9FQ6Tw2f2cu31K


0 0
原创粉丝点击