简介
typedef
可以为某一类型自定义名称,与#define
类似,但又有不同:
- 与
#define
不同,typedef
创建的符号只受限于类型,不能用于值。 typedef
由编译器解释,不是预处理器。- 在其受限范围内,
typedef
比#define
更灵活
用途
(1) 定义一种类型的别名,不只是简单的宏替换。如:
typedef int I; //为整型int取别名I
typedef double D; //为double取别名D
typedef char C; //为char取别名C
typedef unsigned int UI; //为unsigned int取别名UI
用法与普通类型用法一样
I a; //声明一个整形变量a
D b; //声明一个double型变量b
(2) 可以同时作用于指针型的多个对象,如:
char *a,*b; //定义两个字符指针a,b
typedef char * C; //为char*类型取别名C
//可以这样使用
C c,d; //相当于 char *c,*d;
与#define
不同的是:
#define C char *
C s1,s2; //相当于char *s1,s2; 只有s1是指针类型
(3) 用于结构体类型,如:
在C中可以这样用,C++中定义结构体类型变量时不用再加struct了
typedef struct P_point
{
//...
}Point; //为struct P_point取别名Point
Point p; //声明一个结构体类型变量p,相当于struct P_point p;
但是如果在结构体内定义一个指向自己的指针时,仍然要使用原名定义,不可用新名定义,因为在为原名取新名前,编译器并不认识这个名。
typedef struct P_point
{
//...
Point p; //ERROR!
struct P_point *p; //Right!
}*Point; //为struct P_point取别名Point
可以这么写:
typedef struct P_point *Point;
struct P_point
{
//...
Point p; //Right 相当于struct P_point *p;
};
但一般建议还是这样写好:
struct P_point
{
//...
struct P_point *p; //Right!
};
typedef struct P_point *Point;
(4) 为数组定义简洁的名称
typedef int I[10];
I a; //a是一个长度为10的整型数组
I a[5]; //a[5]是一个5行10列的数组
typedef和#define不同
typedef
在声明之后不能往里面再添加任何东西
用其他类型说明符对宏类型进行拓展,但对typedef所定义的类型却不能这样做,如:
#define peach int
unsigned peach a; //没问题
typedef int apple;
unsigned apple a; //错误,非法
typedef带来的陷阱
typedef char* C;
int f(const C,const C);
上面的函数声明中const C
并不相当于const char*
,因为typedef 是用来定义一种类型的新别名的,它不同于宏,不是简单的字符串替换。因此,const C
中的 const 给予了整个指针本身常量性,也就是形成了常量指针char *const(一个指向char的常量指针)
。即它实际上相当于char *const
,而不是const char*(指向常量 char 的指针)
。如果这样定义就相当于const char*
了
typedef const char* C;
int f(C,C);
注意:无论什么时候,只要为指针声明 typedef,那么就应该在最终的 typedef 名称中加一个 const,以使得该指针本身是常量。