typedef用于为现有的数据类型创建一个新的名称(别名)。这个别名在之后的代码中可以用来代替原始的数据类型。
一、typedef的用法
1.为普基本数据类型创建别名
比如为整型创建别名:
typedef int bool;
bool flag = 1; //相当于 int x = 1;
这里将int类型起了一个新的名称bool,然后就可以用bool代替int定义变量。
这就是typedef的第一个作用:提高代码的可读性,使代码更清晰易懂。
其实用define也可以实现同样的效果:
#define bool int
bool flag = 1;
2.为自定义数据类型创建别名
对于C语言,用typedef为结构体命名是特别方便的做法,必须要掌握。
typedef struct {
int x;
int y;
} Point;
Point p; // 相当于 struct { int x; int y; } p;
p.x = 10;
p.y = 20;
使用typedef,定义结构体变量就再也不用每次都写struct了,这就是typedef的第二个作用:简化代码。
共用体、枚举等自定义类型也可以使用typedef创建别名。
3.为数组创建别名
typedef int ARR[5];
ARR a; // 相当于 int a[5];
4.为指针创建别名
typedef char* String; //相当于把char*变成String
String str = "Hello, world!"; // 相当于 char* str = "Hello, world!";
5.为复杂类型定义别名
像指向数组的指针、指向函数的指针,这些复杂的类型声明,简直就是编程界的“噩梦”!使用typedef,会让代码看起来简单些。
(1)为指向数组的指针创建别名
为指向包含5个整型元素的数组的指针定义别名:
typedef int (*PTR_ARR)[5];
这行代码定义了一个指向数组的指针类型,数组包含5个整型元素,之后可以使用PTR_ARR来声明这种类型的指针变量。
(2)为函数指针创建别名
typedef int (*FuncPtr)(int, int);
把一个指向“返回int类型,接受两个int类型参数的函数”的指针,就变成了FuncPtr。
二、typedef与#define的区别
typedef与#define都可以为一个东西起一个新名字,比如给int类型起一个新名叫“zheng”,以下两种方式均可:
typedef int zheng; //别名在后,有分号
#define zheng int //别名在前,无分号
二者的区别在于:
1.服务对象
define的意思是“给……下定义”,就是把A解释成B。typedef与#define长得很像,其实它就是type define。从二者名字可以看出,typedef是专门用于给类型下定义的,其目的是让复杂的类型声明变得更简单、更直观。而#define没有限定范围,也就是说,它什么都可以搞。
2.生效时间
typedef是在编译时处理的;#define是预处理指令,在编译之前进行处理。
#是预处理指令的标志,所以你看到一个含#,一个不含。
3.功能性
一个人越专注、越聚焦,他研究的就越深入,因而也就越牛叉。
typedef这货只关注类型,因此功能也更强大一些。
与define的差别主要体现在:
(1)typedef是在编译时处理的,有类型检查功能;而#define只是简单的文本替换,没有类型检查。
(2)typedef可以为指针类型及更复杂的数据类型定义别名,而#define在定义这些类型时可能会引发一些意想不到的问题(如优先级问题)。
比如:
#define INTPTR1 int*
typedef int* INTPTR2;
INTPTR1 p1, p2;
INTPTR2 p3, p4;
INTPTR1 p1, p2;会声明一个指针变量p1和一个整型变量p2,因为#define只是简单地将INTPTR1替换为int*,即INTPTR1 p1, p2;会被解释为:
int* p1, p2;
所以p1是int*类型,而p2则是int类型。
INTPTR2 p3, p4;会声明两个指针变量p3和p4,因为typedef是将INTPTR2定义为int*类型的别名,所以使用INTPTR2声明的变量都是int*类型的指针。
4.作用域
typedef:有自己的作用域。它定义的类型别名只能在定义的作用域内使用。
#define:没有作用域的限制。它可以在整个文件中使用,除非用了#undef来取消定义。