typedef总结

typedef总结

1、typedef 为类型起别名

typedef的第一个用途,就是起别名,一般是为复杂的声明定义一个新的简单的别名。

格式一:typedef+旧类型名字+新类型名字

格式二:直接使用新的类型名字替代原复杂定义中的类型名字

int(*funcp)(int a, int b);//定义一个函数指针
typedef int(*FP)(int a, int b);//定义一个函数指针类型
FP p1,p2,p3;//同时定义了多个函数指针

作用一是为了方便,为一个复杂的定义起一个简单的别名,使用起来也比较方便,不用每次都输入一串复杂的

typedef   signed          char int8_t;
typedef   signed short     int int16_t;
typedef   signed           int int32_t;
typedef unsigned          char uint8_t;
typedef unsigned short     int uint16_t;
typedef unsigned           int uint32_t;
typedef unsigned long     long uint64_t;
typedef	  signed char  	 	   s8;		
typedef	  signed short 	  int  s16;
typedef	  signed int 		   s32;
typedef	  signed long long int s64;
typedef	unsigned char 		   u8;
typedef	unsigned short int     u16;
typedef	unsigned int 		   u32;
typedef	unsigned long long int u64;

作用二是为了兼容:

typedef有另外一个重要的用途,那就是定义机器无关的类型,例如,你可以定义一个叫REAL的浮点类型,在目标机器上它可以i获得最高的精度:

typedef long double REAL;

在不支持 long double 的机器上,该 typedef看起来会是下面这样:

typedef double REAL;

并且,在连double都不支持的机器上,该 typedef看起来会是这样:

typedef float REAL; 

你不用对源代码做任何修改,便可以在每一种平台上编译这个使用 REAL 类型的应用程序。唯一要改的是 typedef 本身。

2、typedef配合结构体使用

定义一个结构体

struct People{
	int age = 18;
	string name;
};

使用typedef为一个结构体People起一个别名P

typedef struct People{
	int age = 16;
	string name;
}P;

在C语言中,也支持省略原结构体名字的形式,但是这种方式在C++中似乎不太行,会报错。这也提醒我们,C代码就是C代码,C++代码就是C++代码,不要写一些C和C++混合的代码,否则到时候BUG够你受的。

typedef struct {
	int age = 16;
	string name;
}P;

3、typedef配合枚举类型使用

与结构体一样,我们也可以使用typedef来为一个枚举类型起一个别名

typedef enum IRQn{
	Software0_IRQn = 0,
	Software1_IRQn = 1,
	Software2_IRQn = 2,
	Software3_IRQn = 3,
	Software4_IRQn = 4,
	Software5_IRQn = 5,
	Software6_IRQn = 6,
	Software7_IRQn = 7,
	Software8_IRQn = 8,
	Software9_IRQn = 9,
	Software10_IRQn = 10,
}IRQn_Type;

总结

个人认为typedef最重要的作用其实起别名,在有些时候别名的使用会使问题简单不少。

其实本来我来看关于typedef的内容就是因为我在学习嵌入式时遇到这样一段代码,当时是有点晕的,现在清晰了不少,下面来分析分析。

/* 中断服务函数形式 */
typedef void (*system_irq_handler_t) (unsigned int giccIar, void *param);

代码第一行首先定义一个函数指针的类型,用于指向不同中断服务函数,一般用在形参当中,例如:

void system_register_irqhandler(IRQn_Type irq, system_irq_handler_t handler, void *userParam);

在函数system_register_irqhandler的声明中:

参数irq是一个IRQn_Type类型的参数,那么这个IRQn_Type又是什么类型呢,正是我们上面定义的枚举类型。

参数handler是一个system_irq_handler_t类型的形参,这个system_irq_handler_t就是在开头定义的一个函数指针类型。而通过函数指针来调用函数是相当方便的,只需要把指针名字当成函数名字来用就行,是不是很方便。

参数*userParam是一个空指针,用于接收用户参数,在需要的时候可以转换成任意类型的指针变量。

typedef与#define的区别

typedef与#define均可以用来起别名,但是在起别名这一方面,用一个不恰当的解释那就是typedef比#define多一个括号,为什么这么说呢,请看下面代码。

#define P1 int*  //定义P1为int*的别名
void mian()
{
	const P1 p1;  //相当于 const int * p1  (p1为一个常量指针)
	int a = 1;
	p1 = &a;
}

我们都知道在使用#define的时候,计算机是在预处理阶段,将代码中所有的P1替换为int *

因此在这里我们就是相当于创建了一个常量指针。

typedef int* P2;  //使用typedef为int*起别名P2
void main()
{
	int b = 2;
	const P2 p2=&b;  //定义了一个指针常量并初始化
	cout << *p2 << endl;
}

这里的代码const P2 p2;与前面#define部分形式完全一样,但是这个地方定义的p2指针却是一个指针常量,这就是typedef与#define之间的区别,#define仅仅是在程序预编译的阶段进行了简单的替换工作,而typedef是在编译阶段起作用的,作用是将int*捆绑成一个整体,定义为P2,所以在使用代码const P2 p2;的时候const关键字修饰的是后面紧跟的东西,而这个地方后面紧跟着的是一个整体,所以const修饰的就是指针,指针不可修改,因此这是一个指针常量,指针常量在定义的时候需要进行初始化。

所以你现在应该就会理解我为什么说typedef比#define多一个括号,因为typedef将要起别名的原始代码捆绑成了一个整体,加了一个“括号”。

typedef可以同时定义多个指针,而#define稍麻烦一点

#define P1 int*
typedef int* P2;
void main()
{
    P1 a, b, c;
	P2 d, e, f;
	cout << a << b << c << e << d << f << endl;
}

在上面的代码中,a是一个指针,而b和c只是一个int类型的变量;d,e,f均是int*类型的指针变量。

想要用P1来定义多个指针,需要如下操作:

P1 a, *b, *c; //定义三个指针

这里只需要将P1替换为int*就明白了,这里不再解释了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值