1.typedef
typedef 还可以掩饰符合类型,如指针和数组。例如,你不用象下面这
样重复定义有 81 个字符元素的数组:
char line[81];
char text[81];
定义一个 typedef,每当要用到相同类型和大小的数组时,可以这样:
typedef char Line[81];
Line text, secondline;
getline(text);
同样,可以象下面这样隐藏指针语法:
typedef char * pstr;
int mystrcmp(pstr, pstr);
这里将带我们到达第一个 typedef 陷阱。标准函数 strcmp()有两个‘c
onst char *'类型的参数。因此,它可能会误导人们象下面这样声明 mystr
cmp():
int mystrcmp(const pstr, const pstr);
这是错误的,按照顺序,‘const pstr'被解释为‘char * const'(一个指
向 char 的常量指针),而不是‘const char *'(指向常量 char 的指针)。
这个问题很容易解决:
typedef const char * cpstr;
int mystrcmp(cpstr, cpstr); // 现在是正确的
记住:不管什么时候,只要为指针声明 typedef,那么都要在最终的 t
ypedef 名称中加一个 const,以使得该指针本身是常量,而不是对象。
促进跨平台开发
typedef 有另外一个重要的用途,那就是定义机器无关的类型,例如,
你可以定义一个叫 REAL 的浮点类型,在目标机器上它可以 i 获得最高的
精度
typedef long double REAL;
在不支持 long double 的机器上,该 typedef 看起来会是下面这样
typedef double REAL;
并且, 在连 double 都不支持的机器上, 该 typedef 看起来会是这样
typedef float REAL;
3. typedef & #define 的问题
有下面两种定义 pStr 数据类型的方法,两者有什么不同?哪一种更好
一点?
typedef char *pStr;
#define pStr char *;
答案与分析:
通常讲,typedef 要比#define 要好,特别是在有指针的场合。请看例
子:
typedef char *pStr1;
#define pStr2 char *;
pStr1 s1, s2;
pStr2 s3, s4;
在上述的变量定义中,s1、s2、s3 都被定义为 char *,而 s4 则定义
成了 char,不是我们所预期的指针变量,根本原因就在于#define 只是简单
的字符串替换而 typedef 则是为一个类型起新名字。
#define 用法例子:
4. typedef & #define 的另一例
下面的代码中编译器会报一个错误,你知道是哪个语句错了吗?
typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++;
答案与分析:
是 p2++出错了。这个问题再一次提醒我们:typedef 和#define 不同,
它不是简单的文本替换。上述代码中 const pStr p2 并不等于 const char
* p2。const pStr p2 和 const long x 本质上没有区别,都是对变量进行
只读限制,只不过此处变量 p2 的数据类型是我们自己定义的而不是系统固
有类型而已。因此,const pStr p2 的含义是:限定数据类型为 char *的变
量 p2 为只读,因此 p2++错误。
5. typedef & 复杂的变量声明
在编程实践中,尤其是看别人代码的时候,常常会遇到比较复杂的变
量声明,使用 typedef 作简化自有其价值,比如:
下面是三个变量的声明,我想使用 typdef 分别给它们定义一个别名,
请问该如何做?
>1:int *(*a[5])(int, char*);
>2:void (*b[10]) (void (*)());
>3. double(*)() (*pa)[9];
答案与分析:
对复杂变量建立一个类型别名的方法很简单,你只要在传统的变量声
明表达式里用类型名替代变量名, 然后把关键字 typedef 加在该语句的开头
就行了。
>1:int *(*a[5])(int, char*);
//pFun 是我们建的一个类型别名
typedef int *(*pFun)(int, char*);
//使用定义的新类型来声明对象,等价于 int* (*a[5])(int, char*);
pFun a[5];
>2:void (*b[10]) (void (*)());
//首先为上面表达式蓝色部分声明一个新类型
typedef void (*pFunParam)();
//整体声明一个新类型
typedef void (*pFun)(pFunParam);
//使用定义的新类型来声明对象,等价于 void (*b[10]) (void (*)());
pFun b[10];
>3. double(*(*pa)[9])();
//首先为上面表达式蓝色部分声明一个新类型
typedef double(*pFun)();
//整体声明一个新类型
typedef pFun (*pFunParam)[9];
//使用定义的新类型来声明对象,等价于 double(*(*pa)[9])()
pFunParam pa;