typedef <原类型> <新类型名>:是一种语句,为已有数据类型取别名。
作用:使代码更加简洁易懂,用typedef定义数组、指针、结构等类型将带来很大的方便,不仅使程序书写简单而且使意义更为明确,因而增强了可读性。

#define <宏名/标识符> <字符串>:是一种预编译指令,在编译前会把源程序中的<宏名/标识符>用对应的<字符串>来替代。

#define 是C中定义的语法,typedef 是 C++ 中定义的语法,二者在C++中可以通用,但 #define 成了预编译指令,typedef 当成语句处理。
Typedef 和 define 都可以用来给对象取一个别名,但是两者却有着很大不同。
参考资料1 参考资料2

执行时间不同

typedef 在编译阶段有效,所以有类型检查的功能,出现变量和数据类型错误时能及时报错。
而 #define 则发生在预处理阶段,只进行简单机械的字符串替换,不进行任何检查,也不占用程序空间(FLASH ROM)。

功能不同


对于 typedef :

  1. 使类型易于记忆,可定义类型别名,这些类型不只包含内部类型(int,char等),还包括自定义类型(如struct)。
  2. 简化一些比较复杂的类型声明。
  3. 定义与机器无关的类型,提高代码可移植性。在移植代码时,程序员只需要修改 typedef 后的数据类型为宿主机支持的类型即可,而不必修改整个项目中的所有类型。

例如,定义一个叫 REAL 的浮点类型,在目标机器上它可以获得最高的精度:
typedef long double REAL;
在不支持 long double 的机器上,该 typedef 看起来会是下面这样:
typedef double REAL;
并且,在连 double 都不支持的机器上,该 typedef 看起来会是这样:
typedef float REAL;
也就是说,跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改
标准库就广泛使用了这个技巧,比如 size_t 。另外,因为 typedef 是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健。


对于 #define :

  1. 不只可以为数据类型取别名,还可以定义常量、变量、编译开关等,不过他只是单纯的替换。
  2. 可以使用 #ifdef、#ifndef 等来进行逻辑判断,还可以使用 #undef 来取消定义。

作用域不同,因为define是预处理指令,而typedef是语句

#define 没有作用域的限制,只要是之前预定义过的宏,在宏定义以后的程序中都会被影响。而 typedef 有自己的作用域,如果在函数内部则只作用于函数。

对指针的操作

二者修饰指针类型时,作用不同。

1
2
3
4
5
6
Typedef int *pint;
#define PINT int *
const pint p; //等同于pint const p; p不可更改,p指向的内容可以更改,相当于 int * const p;
const PINT p; //p可以更改,p指向的内容不能更改,相当于 const int *p;或 int const *p;
pint s1, s2; //s1和s2都是int型指针
PINT s3, s4; //相当于int *s3,s4;只有一个是指针。 

⭐理解和使用typedef的小技巧

对于一句 typedef 语句:

1
typedef char (*p)(int);

以上语句执行之后,与以下两条语句等效

1
p SHAN;
1
char (*SHAN)(int);

要定义的类型是 char (*)(int),即参数为 int ,返回值类型为字符的函数指针,定义的别名是p。
简单地说,就是把 typedef 后面别名以外的部分视为一个整体,将这个整体用这个别名来表示,以此简化数据类型形式,提高代码可读性。