- 2022-05-09 :添加typedef别名说明和using别名定义
一、typedef与#define比较
typedef
和#define
功能的共同点
例如:
1 |
表示预处理器用BYTE
替换unsigned char
1 | typedef unsigned char BYTE |
表示编译器给类型unsigned char
起了一个别名BYTE
typedef
和#define
的区别
#define
只是替换,由预处理器执行,#define A B
即意味着将B用A替换。
与#define
不同,typedef
具有以下特点:
typedef
给出的符号名称仅限于类型,而不是数值。typedef
的解释由编译器执行,不是简单的文本替换。- 虽然范围有限,但是在有限范围内
typedef
比#define
更灵活。
(1) 连续定义多个变量时typedef
和#define
的区别。
1 | typedef char * STRING |
表示编译器把STRING
解释为一个类型的标识符,该类型指向char
。
所以:
1 | STRING name, sign; |
相当于:
1 | char * name, * sign; |
1 |
表示预处理器将用STRING
替换char *
标识符。
1 | STRING name, sign; |
将被翻译成:
1 | char *name, sign; |
结果是name
是一个指针,sign
是一个字符类型。
(2) #define
可以使用其他类型名对宏类型名进行拓展,但typedef
定义的类型名不能用其他类型进行拓展。
1 |
|
二、typedef的主要用法
用法一:
1、为基本数据类型定义一个别名,不是简单的宏替换。可以用作同时声明多个指针对象。比如:
1 | char * pa, pb; // 这只是声明了一个指向字符的指针 |
换一种可行的方式:
1 | typedef char * PCHAR; |
实际上等同于:
1 | char * pa, *pb; |
2、为数组定义简洁名称。
示例代码为:
1 | typedef int INT_ARRAY_100[100]; |
番外:
c++11新标准中引入using
进行别名定义,使用更加方便、简洁,示例为数组定义简洁名称:
1 | using INT_ARRAY_100 = int[100]; |
用法二:
1、用在旧的C代码中,帮助struct。以前的代码中,声明struct新对象时,必须要带上struct,即形式为: struct 结构名对象名,如:
1 | struct tagPOINT1 |
而在C++中,则可以直接写:结构名对象名,即:
1 | tagPOINT1 p1; |
1 | typedef struct tagPOINT |
1 | POINT p1; // 这样就比原来的方式少写了一个struct |
2、另外,还可以为自定义数据类型(结构体、共用体和枚举类型)定义简洁的类型名称。
以结构体为例,下面我们定义一个名为Point的结构体:
1 | struct Point |
调用这个结构体:
1 | struct Point oPoint1={100,10,0}; |
在这里,结构体 struct Point
为新的数据类型,在定义变量的时候均要向上面的调用方法一样有保留字 struct
,而不能像 int
和 double
那样直接使用 Point
来定义变量。现在,我们利用 typedef
定义这个结构体,如下面的代码所示:
1 | typedef struct tagPonit |
在上面的代码中,实际上完成了两个操作:
(1)定义了一个新的结构体类型,代码如下:
1 | struct tagPoint |
现在已经定义了一个新的结构体类型tagPoint
。
(2)使用typedef
为这个新的结构体起一个别名,叫Point,即:
1 | typedef struct tagPoint Point; |
因此,现在你就可以像 int 和 double 那样直接使用 Point 定义变量,如下面的代码所示:
1 | Point oPoint1={100,10,0}; |
使用typedef规范定义结构体的方法:
1 | struct tagNode |
推荐使用这种使用typedef
规范定义结构体的方法,在定义链表时经常会用到。
用法三:
用typedef来定义与平台无关的类型。
多使用在跨平台移植程序时!
比如定义一个叫 REAL
的浮点类型,在目标平台一上,让它表示最高精度的类型为:
1 | typedef long double REAL; |
在不支持 long double
的平台二上,改为:
1 | typedef double REAL; |
在连 double
都不支持的平台三上,改为:
1 | typedef float REAL; |
也就是说,当跨平台时,只要改下 typedef
本身就行,不用对其他源码做任何修改。
标准库就广泛使用了这个技巧,比如size_t
。另外,因为typedef
是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健。