本文基于一个简单的Simulink生成的代码,研究C语言中typedef关键字的作用。
本科学过C语言的朋友都知道数据类型的概念。C语言中有整型,如char、int、short等等;也有浮点类型,如float、double。
typedef关键字就是给这些数据类型起一个别的名字,然后用这个自己起的名字来定义变量。比如如下语句就把char类型起了个新的名字叫int8。然后用int8定义了一个变量a1。
typedef char int8; int8 a1;那么为啥要整这么一出,直接用基础类型来定义变量不行吗?后文博主会结合一个Simulink生成的代码,研究其中的原因。
在生成的头文件里面可以看到结构体的定义用到了typedef关键字。 从中摘取如下代码片段来研究一下:
28 typedef struct { 29 real_T In1; /* '<Root>/In1' */ 30 } ExtU_demo_T;ExtU_demo_T就是用typedef定义的结构体类型,然后可以用ExtU_demo_T作为类型声明新的结构体变量。打开demo.c源文件可以看到,在源文件中用ExtU_demo_T定义了变量demo_U,用ExtY_demo_T定义了变量demo_Y。
在rtwtypes.h头文件中专门有一组typedef,它们把一些基本类型,如char、float等,定义成别的名字。 然后定义变量的时候不去用基础类型定义,而是用int8_T,real32_T这些自己起名的类型去定义变量。 以前博主对此很费解,为啥要没事找事转一道。后来接触到MISRA-C规范后,才明白里面的意义。MISRA-C 2004规范的6.3条中说到,应该使用指示了大小和符号的typedef以代替基本数据类型。 所以,把unsigned char用typedef转换成uint8_T的话,后面定义变量的时候就可以很清楚的知道这个变量是uint8的,范围是0~255。
另外,32位系统和64位系统中,基础类型对应的字节长度可能不同。如果整个工程中的代码全都是基础类型,再移植代码到新系统的时候可能要全部改一遍。而如果用了typedef,只需要改一下typedef这一句就行了。
在Simulink建模中可以用AliasType把Simulink中的基本类型定义一个别名,比方说定义一个物理单位,然后用别名作为数据类型去仿真。这种情况下生成的c代码会有对应的typedef定义类型。
比如说,在Matlab命令行定义一个AliasType为Hz(赫兹)。
>> Hz = Simulink.AliasType; >> Hz.BaseType = 'single'; >> Hz Hz = AliasType - 属性: Description: '' DataScope: 'Auto' HeaderFile: '' BaseType: 'single'然后工作空间会出现定义的AliasType。 然后在Simulink模型中把Gain模块的输出类型改成Hz。 然后再次生成代码,可以看到代码中对应的用typedef定义的Hz。
目前博主工作中遇到的typedef主要就是以上3种非常常见的情况。因为经验有限,如果同行们有其他的观点和见解,欢迎在评论区补充,谢谢!
>>返回个人博客总目录