C语言之typedef的使用

*关于typedef之前使用过,但一直没有深入研究,趁着这个时候换平台研究下,所与C语言相关的内容没有完全吃透的东西再重新( ̄~ ̄) 嚼一嚼。那就开始吧。

typedef关键字可以用于给数据类型定义一个别名,比如说DL/T645-2007通信协议,大家叫的时候都觉得名字在长了,所以注给他取了个别名645-07,所以只要大家说这个就知道是在讲DL/T645-2007了。

当你定义了一个结构体时,每次创建一个结构体都要使用struct+结构体名的方式,而用了typedef之后,只要一个结构体别名就可以创建了。

struct	sttaskParam	//本名				
{
	unsigned char ucParamActive;
	unsigned char ucStartActive;			//参数F67、F68:定时上报1类数据任务启动/停止设置
	unsigned char ucTimeInter;				//定时上报周期
	unsigned char ucTimeUnit;				//定时上报周期单位
	unsigned char ucRInter;				//曲线数据抽取倍率R		
	unsigned char ucDUIDNum;				//数据单元标识个数n
	STDATETIME	  stStartActive;			//发送基准时间
	STDATAUNITID  stDUID[CON_TASK_DATAUNITNUM];	//数据单元
}STTASKPARAM;
struct sttaskParam Taskparam;	//必须使用struct

typedef struct							//本名可以省略
{
	unsigned char ucParamActive;
	unsigned char ucStartActive;			//参数F67、F68:定时上报1类数据任务启动/停止设置
	unsigned char ucTimeInter;				//定时上报周期
	unsigned char ucTimeUnit;				//定时上报周期单位
	unsigned char ucRInter;				//曲线数据抽取倍率R		
	unsigned char ucDUIDNum;				//数据单元标识个数n
	STDATETIME	  stStartActive;			//发送基准时间
	STDATAUNITID  stDUID[CON_TASK_DATAUNITNUM];	//数据单元
}STTASKPARAM;					//结构体别名
STTASKPARAM			stTask1Param[CON_MAX_TASKNUM];	//不使用struct

并且有了别名,本名我都可以不要了(当然你也可以加上)。
虽然说简化写法是一个不错的功能,但却不是一个很必要的功能。那么肯定有别的好处才是。
我们知道C语言定义数据类型的时候只定义了它们之间的关系,但却没有具体定义它们的大小。比如 short 的长度只规定了不大于 int,long的长度不小于 int,int是多大也没确定,所以你会看到51单片机的int大小为两个字节,而在stm32中的长度为 4 字节。所以这个时候有必要使用一个别名来代替具体的数据类型,并且最好这个别名有一定的说明性,所以你会看到stm32库函数有这么一堆申明:

 /* exact-width signed integer types */
typedef   signed          char int8_t;
typedef   signed short     int int16_t;
typedef   signed           int int32_t;
typedef   signed       __int64 int64_t;

    /* exact-width unsigned integer types */
typedef unsigned          char uint8_t;
typedef unsigned short     int uint16_t;
typedef unsigned           int uint32_t;
typedef unsigned       __int64 uint64_t;

这样一旦后期换了平台,我就知道怎么根据新平台修改这个定义了,因为这个别名已经有长度、符号信息了。

从51过来的读者可能会说,干嘛要用 typedef,使用 #define (关于#define可以查看#define小节)也能有相同的效果。确实是,但是 #define 严格来说它只是用来替换的,而typedef 是专业的。所以使用 #define 可能一不小心就会给你挖坑了。

#define	puchar   unsigned char *			//puchar被替换的是,之前的部分

puchar  pStr1,pStr1;							//pStr1是指针,pStr2不是指针

比如上面的,虽然本意是定义两个指针的,但是 #define 比较笨,只会简单替换,所以替换后成了这个样子:

unsigned char * pStr1,pStr1;							//pStr1是指针,pStr2不是指针

所以只有一个被定义成了指针,而如果使用 typedef 就没有这个问题。

typedef  unsigned char *	  puchar   ;				//puchar是别名,

puchar  pStr1,pStr1;								//pStr1,pStr2都是指针

虽说typedef在取别名上是专业的,但是如果你不熟悉而贸然使用的话也可能会为你挖坑的。下面介绍使用typedef时的一些坑:

##1、const
在和const一起使用的时候,本想定义一个指向的字符为常量的变量指针,但因为typedef的特殊性,不是简单的替换,所以最终的定义的是指向的字符为变量的常量指针。

typedef char * pPCHAR;				//定义字符指针的别名
int str(const pPCHAR, const pPCHAR);
/*想定义  指针为变量,指向的字符为常量的  参数
实际上是 指针为常量,指向的字符为变量*/

解决的办法就是在typedef中加const即可:

typedef  const char * pPCHAR;				//定义字符指针的别名
int str(pPCHAR, pPCHAR);					//指针为常量,指向的字符为变量

怎么看哪个可以变,哪个不可以变呢?

就看const修饰哪一个了。如果说const离char近,就是字符不变,如果const离指针名比较近,那就是指针不变,其他类似的,好好理解一下就差不多了。如果实在不理解也没关系,忘记了再回来查一下就行,但是你得知道使用typedef有这么一个坑在就行了。

##2、存储类
typedef 不影响对象的存储特性,但是在语法上它却是一个存储类的关键字,就像 auto、extern、static、register等关键字一样。所以不能和存储类的关键字一起使用:

typedef extern char* pPCHAR1;
typedef static char* pPCHAR2;
typedef auto char* pPCHAR3;
typedef register char* pPCHAR4;

错误的原因就是不能声明多个存储类关键字,typedef 已经申明了存储属性,不允许再有第二个了。这个坑还是不容易跳进去的,毕竟编译器能帮你找出问题来,不用你担心。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值