typedef
概念
C语言允许用户使用 typedef 关键字来定义自己习惯的数据类型名称。 示例:
代码语言:javascript复制typedef int BOOL;//定义一个布尔类型
#define TRUE 1
#define FALSE 0
//定义好之后,就可以像使用基本类型数据一样使用它了,如下面的代码所示:
BOOL bflag=TRUE;
typedef的4种用法
1.为基本数据类型定义新的类型名 比如跨平台时,有的机子不支持long double,但有需要高精度的一个类型参与计算,那就可以进行如下定义:
代码语言:javascript复制typedef long double ACCURACY;//当跨平台时,只需修改long double的类型就可以了,如下
typedef double ACCURACY;
2.为自定义数据类型(结构体、共用体和枚举类型)定义简洁的类型名称
代码语言:javascript复制//以结构体为例,下面我们定义一个名为 Point 的结构体:
struct Point
{
double x;
double y;
double z;
};
//在调用这个结构体时,我们必须像下面的代码这样来调用这个结构体:
struct Point oPoint1={100,100,0};
struct Point oPoint2;
上面是传统定义方法,下面是利用typedef的升级版:
代码语言:javascript复制typedef struct tagPoint
{
double x;
double y;
double z;
} Point;
//在上面的代码中,实际上完成了两个操作:
//1、定义了一个新的结构类型,代码如下所示:
struct tagPoint
{
double x;
double y;
double z;
} ;
//其中,struct 关键字和 tagPoint 一起构成了这个结构类型,无论是否存在 typedef 关键字,这个结构都存在。
//2、使用 typedef 为这个新的结构起了一个别名,叫 Point,即:
typedef struct tagPoint Point
//综上:现在就可以像 int 和 double 那样直接使用 Point 定义变量,如下面的代码所示:
Point oPoint1={100,100,0};
Point oPoint2;
如果上面结构体的声明没看懂可以先看下这个:
代码语言:javascript复制#include <stdio.h>
typedef int A,*B;//定义两个类型,一个整型的别名A,一个整型指针B,这两个变量没有联系,谁也代表不了谁,都是独立的。
int main()
{
A aa=10;
B bb;
*bb=12;
printf("&aa=%pn",&aa);
printf("bb=%pn",bb);
printf("aa=%dn",aa);
printf("*bb=%dn",*bb);
return 0;
}
#include <stdio.h>
#include <string.h>
#define MAXSIZE 100 // 顺序表的最大长度
typedef int ElemType; // 自定义顺序表的数据元素为整数。
typedef struct
{
ElemType data[MAXSIZE]; // 用数组存储顺序表中的元素
unsigned int length; // 顺序表中元素的个数
}SeqList,*PSeqList;//这个就是定义两个类型,一个是结构体别名SeqList和一个结构体指针PSeqList。
3.为数组定义简洁的类型名称
代码语言:javascript复制//与为基本数据类型定义新的别名方法一样,示例代码如下所示:
typedef int INT_ARRAY_100[100];
INT_ARRAY_100 arr;
4.为指针定义简洁的名称
代码语言:javascript复制//对于指针,我们同样可以使用下面的方式来定义一个新的别名:
typedef char* PCHAR;
PCHAR pa;
//例如有下面这种类型,上面这个方法就有大用处了:
int *(*a[5])(int,char*);
// PFun是我们创建的一个类型别名
typedef int *(*PFun)(int,char*);
// 使用定义的新类型来声明对象,等价于int*(*a[5])(int,char*);
PFun a[5];
typedef 和 #define 的区别
typedef 在表现上有时候类似于 #define,但它和宏替换之间存在一个关键性的区别。正确思考这个问题的方法就是把 typedef 看成一种彻底的“封装”类型,声明之后不能再往里面增加别的东西。
- 可以使用其他类型说明符对宏类型名进行扩展,但对 typedef 所定义的类型名却不能这样做。如下所示:
#define INTERGE int
unsigned INTERGE n; //没问题
typedef int INTERGE;
unsigned INTERGE n; //错误,不能在 INTERGE 前面添加 unsigned
- 在连续定义几个变量的时候,typedef 能够保证定义的所有变量均为同一类型,而 #define 则无法保证。例如:
#define PTR_INT int *
PTR_INT p1, p2;
经过宏替换以后,第二行变为:
代码语言:javascript复制int *p1, p2;
这使得 p1、p2 成为不同的类型:p1 是指向 int 类型的指针,p2 是 int 类型。
相反,在下面的代码中:
代码语言:javascript复制typedef int * PTR_INT
PTR_INT p1, p2;
p1、p2 类型相同,它们都是指向 int 类型的指针。