20170726 --iRonMan
C语言允许用户使用typedef关键字来定义自己习惯的数据类型名称,来替代系统默认的基本类型名称。
举个简单的例子,C语言在C99之前并未提供布尔类型,但我们可以使用typedef关键字来定义一个简单的布尔类型,如下
typedef int BOOL; //给int基本类型去了新名字BOOL
#define TRUE 1 //定义TRUE为1,即可以用TRUE来表示1(为真)
#define FALSE 0
定义好之后就可以像使用基本类型一样使用定义的BOOL
BOOL bflag=TRUE; //等价于 int bflag=1
学习C语言,应该对typedef的四种应用形式有所掌握。
1.为基本数据类型定义新的类型名
定义与平台无关的类型,即不管在什么平台上都可以使用这个新的类型名,有利于跨平台移植程序
比如,要定义一个叫REAL的浮点类型,在目标平台1上,让它表示最高精度的浮点类型,即
typedef long double REAL;
在不支持long double 的平台2上,改为
typedef double REAL;
甚至还可以连double都不支持的平台3上,改为
typedef float REAL;
这样,当移植程序时,我们只需要修改一下typedef 的定义即可,而不用对源代码中出现的同种数据类型一个一个修改。惊不惊喜~
2.为自定义数据类型(结构体、共用体和枚举类型)定义简洁的类型名称
以结构体为例,定义一个名为Point的结构体:
struct Point
{
double x;
double y;
double z;
}; //注意别忘了分号
此时结构体struct Point 为新的数据类型,调用这个结构体来定义变量时必须保留字struct,而不能像int 和 double一样直接使用。当使用的次数多了是不是显得很麻烦?
调用
struct Point oPoint1={100,100,0}; //定义一个结构体oPoint1并初始化
struct Point oPoint2;
用typedef 定义这个结构体,如下:
typedef struct tagPoint //这部分代码分成两部分
{ //(1)定义tagPoint结构体,构成新的结构类型struct tagPoint
double x; //(2)使用typedef为这个结构体取一个别名Point
double y; //即typedef struct tagPoint Point;
double z;
}Point;
另外,这里做一下延伸,记录一下可能编译器会报错的点:
typedef struct tagNode
{
char *pItem;
pNode pNext;
} *pNode;
上面这个结构体中,错在哪里呢?可能有人会觉得错在结构体中包含了指向自己的指针,但真是这样吗?其实,C语言允许结构体中包含指向自己的指针。究其原因,根本问题在于typedef的应用。
在结构体的建立中遇到了pNext声明,其类型是pNode, 但是结构体本身还没建立完,编译器还不认识pNode是谁,所以自然会报错。那要怎么改?
typedef struct tagNode
{
char *pItem;
struct tagNode *pNext; //*是跟着结构体的,struct tagNode *
} *pNode;
3.为数组定义简洁的类型名称
typedef int INT_ARRAY_100[100];
INT_ARRAY_100 arr;
4.为指针定义简洁的名称
typedef char* PCHAR;
PCHAR pa; //==char* pa
上面的指针比较简单,使用typedef看起来意义不大,但是遇到复杂的情况,优势就出来了:
//PFun是我们创建的一个类型别名
typedef int *(*PFun)(int, char*);
//使用定义的新类型来声明对象,等价于int *(*a[5])(int, char*);
PFun a[5];
ok,关于关键词typedef的用法介绍就到此结束啦,这些内容是看了马伟先生著的 ‘Writing Solid Code’ 后的一些收获。要是朋友们有什么补充的还请不吝赐教~