用途一: 定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如:# [; R; S- z9 J3 \9 Q4 }
char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针,. S' D# H+ J! @5 H, A0 O. |( T$ B
// 和一个字符变量;
- M% [3 s. ^& m1 u& G 以下则可行:# O' V9 m6 ^; V, ~$ |
typedef char* PCHAR; // 一般用大写; Z. E4 E5 m- b4 [* A
PCHAR pa, pb; // 可行,同时声明了两个指向字符变量的指针3 H. }, e9 b+ k8 k
虽然:; Y4 e2 M: N2 Q) [
char *pa, *pb;
6 r6 w4 Y5 M/ {7 y: o- J6 O8 n y 也可行,但相对来说没有用typedef的形式直观,尤其在需要大量指针的地方,typedef的方式更省事。
6 f) q0 \- }( } 用途二:( k: w# ~# k/ @5 E
用在旧的C代码中(具体多旧没有查),帮助struct。以前的代码中,声明struct新对象时,必须要带上struct,即形式为: struct 结构名 对象名,如:
( U. R, Z* i; c2 M6 Z8 u% i; z struct tagPOINT1
/ d: O" y" y v/ S4 V- y! @; @% h1 q! \! Z {/ s! z* }3 X! _0 Y
int x;" W: \0 c, @% r
int y;
$ ~4 F9 K' I. L1 d) }' P; ~ };: R, F# H. E. ]2 x
struct tagPOINT1 p1;. N c7 E: Z# O3 d
而在C++中,则可以直接写:结构名 对象名,即:2 G9 d6 c; q2 V' U" j9 w
tagPOINT1 p1;" A$ O3 Y# @. C# S
估计某人觉得经常多写一个struct太麻烦了,于是就发明了:! u7 v7 _& m7 ^
typedef struct tagPOINT
* R& t% F; M( c# B U7 }9 e( _: X {0 n' B# S/ C+ t" q( B+ W$ d, i' E
int x;4 q5 r( B. S6 ^
int y;7 i1 [. b$ D. f4 h* u" A
}POINT;
4 o0 `. G* B4 V+ t POINT p1; // 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候1 D& k- t: r! s. G+ }2 w# ^
或许,在C++中,typedef的这种用途二不是很大,但是理解了它,对掌握以前的旧代码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。5 C$ V" X. L8 S- z0 F3 s
用途三:
+ r0 B( {; Y: f: } 用typedef来定义与平台无关的类型。
' w; U& B' j$ ]: o8 E' c( J1 r# { 比如定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型为:
$ n7 Z2 w8 q" f5 A) r4 q- z typedef long double REAL;% }6 G# i: ?& }
在不支持 long double 的平台二上,改为:
. Z& W' I0 ~) |! }8 ~+ g typedef double REAL;/ n! Q U& `: z* z/ d( j
在连 double 都不支持的平台三上,改为:
1 d' y3 Z* e l( i typedef float REAL;
4 e# c8 y, _/ x9 o/ |" b" c* u 也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。$ @' L- z# N% ~
标准库就广泛使用了这个技巧,比如size_t。
, V8 B$ Z* `7 Q
# U% I( j' Q* }* @9 D% i: Y 另外,因为typedef是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健(虽然用宏有时也可以完成以上的用途)。 |