学习C语言的头文件包含巧妙用法(defineEXT)

一、学习C语言的头文件包含巧妙用法重要的是代码的观赏和可读性提高了。在程序中如果全局变量比较多,包含几个结构和数组,如果这些全部定义的话势必会占大量的内存,有可能还会导致单片机内存不够,如果能让几个不同时用到的数组和结构变量共享一段内存,则能省出很多的内存空间。

1.了解C语言头文件如何包含巧妙的用法

当一个头文件被多个C文件包含时,并且这些C文件的公共变量都定义在头文件中时,编译时会出现重复定义,导致编译失败。 通常我们会采用以下两种方法来解决问题。 上述问题。 (为了让问题更清楚,我们假设三个C文件C1、C2、C3和一个头文件H1。C1、C2、C3有两个公共变量V1和V2) 1、在C1文件中定义变量V1和V2 V2,在C2和C3文件中对V1和V2使用extern声明; 2、在C1文件中定义变量V1和V2,在H1中对V1和V2使用extern声明,然后在C2和C3文件中包含H1; 很明显,上面两种方法都需要写V1和V2至少两次,一次定义,一次外部声明,而且它们不在同一个文件中。 这不利于管理和修改。 有没有办法放置这些公共变量? 在一个文件中,并且只需要写入一次? 首先,我们将所有要使用的公共变量写入 com.h 文件中。 在定义每个变量之前添加符号 EXT_。 当头文件被main.c函数包含时,定义EXT_为空,表示com.h中的变量是在main.c中定义的。 当包含在其他文件中时,将EXT_定义为extern,表示外部声明,如:Com.h文件:

//避免重复定义

#ifdef根

#定义EXT_

#别的

#定义EXT_外部

#万一

//全局变量EXT_u8变量1;

//该变量在三个C文件Main.c中使用

#define root //在包含com.h之前定义root

#include“com.h”

2. 使用结构体定义总线或外设地址。 当一个整体包含多个不同类型的成员时,通常使用结构体来定义结构体变量,以便内存将这些变量以递增的方式分配给相邻的变量。 地址(错位的地方会有填充),按照“结构体名.成员名”的方法访问结构体中的成员,这就是访问结构体变量的方式; 但还有一个指向结构体变量的指针,可以将地址转换为结构体类型的指针,比如寄存器的定义:(以下摘自STM32固件函数库,关于通用输入输出口)

类型定义结构

vu32 CRL; //0

vu32 CRH; //偏移4

vu32 IDR; //偏移8

vu32 ODR;

vu32BSRR;

vu32 BRR;

vu32LCKR;

} GPIO_TypeDef;

#define GPIOA_BASE ((u32)0x40010800) //GPIOA基址为0x40010800

#定义GPIOA (GPIO_TypeDef *) GPIOA_BASE; //强制类型转换为GPIO_TypeDef类型的指针

这样,在操作GPIOA寄存器时,只需要这样写

读取:X= GPIOA->CRL; 写入:GPIOA->CRL=X; 或阅读:如下:

#定义GPIOA_CRL 0x40010800

#定义GPIOA_CRH 0x40010804

#定义GPIOA_IDR 0x40010808

#定义GPIOA_ODR 0x4001080C

#定义GPIOA_BSSR 0x40010810

#定义GPIOA_LCKR 0x40010814

显然,第一种写法更加形式化,并且在定义多个GPIO时,只需要将其他GPIO的基地址强制转换为该结构类型的指针即可。 我们来看一个定义外部总线的例子:

类型定义结构

vu8 CH375_数据;

vu8 CH375_CMD; //偏移1

CH375_TypeDef;

#定义CH375((CH375_TypeDef *)0x6c000000)

CH375-> CH375_DATA=数据; //写入数据到地址0x6c000000

CH375-> CH375_CMD=cmd; //写入命令到地址0x6c000001

这个怎么样? 是不是方便很多呢? 重要的是代码的查看性和可读性得到了提高。

3. 使用枚举数据类型来定义特定状态。 在实际问题中,有些变量的取值被限制在一个有限的范围内。 例如,一个函数在运行过程中会返回几种具体的状态:操作成功、操作失败、忙等,如果我们在函数中直接用0、1、2来表示这三种状态,有时数值和实际状态可能不一样不匹配,导致状态设置和状态判断错误。 那么我们可以在程序中使用宏或者枚举来提前定义这些状态。

例如:使用宏定义:

#defineSucess 0

#定义失败1

#定义忙2

使用枚举

类型定义枚举

成功 = 0,失败,忙碌

标志状态;

4. 使用union类型定义共享内存空间。 联合类型定义的数据是与多个成员共享同一内存空间。 空间的大小是最大成员的大小。 它的用法与结构体完全相同,但值得注意的是,它不能同时引用多个成员,并且一次只能使用其中一个。 如果程序中有很多全局变量,包括几个结构体和数组,如果这些都定义了,必然会占用大量的内存,也可能导致单片机内存不足。 如果可以在不同的时间使用多个数组和结构体,变量共享一段内存,可以节省大量的内存空间。 例如,如果下面的输入和输出不是同时执行,则它们可以共享相同的内存空间。

联盟

结构体

无符号字符标志;

无符号字符类型;

无符号字符状态;

无符号长 DataLen;

无符号字符缓冲区[64];

}数据输出;

结构体{

无符号字符标志;

无符号字符类型;

无符号字符状态;

无符号长 DataLen;

无符号字符缓冲区[64];

数据输入;

} 中国银行;

C语言博大精深、丰富多彩。 如果使用得好,就能很好地发挥它的作用。 同时,对于一个设计师来说,学习好的编程方法,养成良好的编程习惯也是极其重要的。 以上四点都是我自己积累和学习的一些总结,希望能够与大家交流,共同学习,共同提高。

我们的官方QQ群:281549832

在此感谢大家的大力支持!

单片机

蓝桥杯单片机开发板的数码管的基本知识点解读

2024-5-10 5:00:57

单片机

帮第一书记支招艾衍辉树莓红似火蓝莓营养多

2024-5-10 6:01:38

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索