一、前言
虽然都是为一种类型创建自定义的名字,但之间还是有很打的差别的。
使用形式:
#define my_int int
typedef int my_int
二、typedef的用途
1. 用途一:
用作同时声明指针类型的多个对象,比如:
int *pa,pb;
//相当于
int *pa;
int pb;
这里相当于只定义了一个指向int
型变量的指针pa
,而pb
是int
整型变量,不是指针。
但是typedef
可以实现定义多个指针类型变量
typedef (int*) P_INT;
P_INT pa,pb;
虽然使用int *pa, *pb;
也可以完成上面操作,但是没有typedef
直观简单,尤其在大量需要指针的地方。
2. 用途二:
在以前代码中,声明 struct
新对象时:struct 结构名 对象名
struct RecTangle
{
int length;
int width;
};
// 声明一个新对象Rec1
struct RecTangle Rec1;
使用typedef
则可以比原来少写struct
,在大量使用时比较省时省力。
(需要注意在C++中可以直接结构名 对象名
,即:RecTangle Rec1;
)
typedef struct RecTangle
{
int length;
int width;
} RecT;
// 声明一个新对象Rec1
RecT Rec1;
3. 用途三:
用typedef来定义与平台无关的类型。
- 比如定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型为:
typedef long double REAL
- 在不支持
long double
的平台二上,改为:typedef double REAL
- 在连
double
都不支持的平台三上,改为:typedef float REAL
当代码跨平台时,只需要修改typedef
就可以,不用去改其他源码,比如经常使用的uint_32_t
:
4. 用途四:
给指向函数的指针类型起别名
#include <stdio.h>
//给指向函数的指针,起了个别名叫MySum
//被指向的函数接收2个int类型的参数,返回值为int类型
typedef int (*MySum)(int ,int);
// 定义一个sum函数,计算a,b的和
int sum(int a, int b)
{
int sum = a + b;
return sum;
}
int main()
{
// 定义一个指向sum函数的指针变量p
MySum p = sum;
// 利用指针变量p调用sum函数
printf("MySum Result: %d\n",p(4,5));
return 0;
}
5. 用途五:
为复杂的声明定义一个新的简单的别名。
方法是:在原来的声明里逐步用别名替换一部分复杂的声明,如此循环,把带变量名的部分留在最后替换,得到的就是原声明的最简化版。eg:
// 原声明
void (*b[10]) (void (*)());
// 先替换右边括号里的(void (*)()) ,pFunParam为别名1
// 给指向函数的指针类型,起了个别名叫pFunParam
typedef void (*pFunParam)();
// 再替换左边的变量,pFunx为别名2
typedef void (*pFunx)(pFunParam);
//原声明的最简化:
pFunx b[10];
** 还在理解中,上面代码怎么去做应用和实现 **
理解复杂声明可用“右左法则”:从变量名看起,先往右,再往左,碰到一个圆括号就调转阅读的方向;
括号内分析完就调出括号,还是按先右后左的顺序循环,直到整个声明分析完,例:
int (*fun)(int *);
//首先找到变量名fun,外面有一对圆括号,左边有*号,说明fun是一个指针
//然后看右边圆括号,这说明(*fun)是一个函数,所以fun是一个指向这类函数的指针,即函数指针
//这类函数具有int*类型的形参,返回值类型为int
int (*fun[5])(int *);
//fun右边是[]运算符,说明fun具有5个元素的数组
//fun左边有*,说明fun的元素是指针(这里的*不是修饰fun,而是修饰fun[5]数组的内容)
//看右边括号,说明fun数组的元素是函数类型的指针,它指向的函数具有int*类型的形参,返回值类型为int
三、区别
#define
在“预处理过程”进行宏的替换与展开,不进行正确性的检查,无脑替换,不管正确与否都带入替换,安全性差,在编译阶段可能才会发现错误报错。#define Add(a,b) (a+b) // 正确 Add(5+4) // 错误 Add(x+4)
typedef
在“编译过程”,用来给标识符或者关键字起一个别名- 建议能使用
typedef
就不使用#define
#define
行末没有分号