问题来源
- 例如野火STM32F407霸天虎V2的点亮LED灯的项目为例。
下面是bsp_led.h文件
#ifndef _BSP_LED_H_
#define _BSP_LED_H_
#include "stm32f4xx.h"
void LED_GPIO_Config(void);
#endif
- 各种的视频教程都直接告诉你结论,这个条件编译的写法可以预防重复编译,有些人可能一下就明白为什么,而有些人却想不明白它是如何做到的。
- 对于刚开始学习单片机的人来说,这确实难以理解,主要是因为开始的时候代码量并没有很大,重复编译的问题还不太明显;但是对于久经沙场的老手,长期接触代码量很大的项目,就很清楚为什么要预防重复编译。
- 下面我会假设一个不算小也不算大的项目例子来说明,这种条件编译的写法是如何预防重复编译的。
重复包含led.h的场景例子
假设main.c里的内容是这样的:
#include "bsp_led.h"
#include "bsp_key.h"
│ └── #include "bsp_led.h" ← 间接又包含了led.h!
#include "bsp_tim.h"
└── #include "bsp_led.h" ← 再次包含!
- 你应该知道:#include预处理命令,其本质就是在编译之前进行文本替换。
假设这些.h文件没有用条件编译
- 我们假设没有写条件编译,并且各个.h文件的内容如下:
bsp_led.h:
(led的代码)
bsp_key.h
#include "bsp_led.h"
(key的代码)
bsp_tim.h
#include "bsp_led.h"
(tim的代码)
那么通过#include进行文本替换后的main就是这样的:
(led的代码)
(led的代码)
(key的代码)
(led的代码)
(tim的代码)
这时我们发现bsp_led.h的内容被重复包含了。
当.h文件使用条件编译后
- 如果我们加上条件编译:
bsp_led.h:
#ifndef _BSP_LED_H_
#define _BSP_LED_H_
(led的代码)
#endif
bsp_key.h
#ifndef _BSP_KEY_H_
#define _BSP_KEY_H_
#include "bsp_led.h"
(key的代码)
#endif
bsp_tim.h
#ifndef _BSP_TIM_H_
#define _BSP_TIM_H_
#include "bsp_led.h"
(tim的代码)
#endif
这时通过#include进行文本替换后的main就是这样的:
/* 这里是bsp_led.h */
#ifndef _BSP_LED_H_
#define _BSP_LED_H_
(led的代码)
#endif
/*—————-*/
/* 这里是bsp_key.h */
#ifndef _BSP_KEY_H_
#define _BSP_KEY_H_
/* 这里包含了bsp_led.h */
#ifndef _BSP_LED_H_
#define _BSP_LED_H_
(led的代码)
#endif
/*——————–*/
(key的代码)
#endif
/*—————-*/
/* 这里是bsp_tim.h */
#ifndef _BSP_TIM_H_
#define _BSP_TIM_H_
/* 这里包含了bsp_led.h */
#ifndef _BSP_LED_H_
#define _BSP_LED_H_
(led的代码)
#endif
/*——————–*/
(tim的代码)
#endif
/*—————-*/
- 这里大家可以自己捋一下预编译后剩下什么(预编译后宏定义会被删除:#ifndef #define #endif),其实到这里再按照上面的代码自己顺一下就豁然开朗了。
- 将你自己顺过来的有效代码和下面的对一下,看看有没有错。
- 最后剩下的有效代码如下:
(led的代码)
(key的代码)
(tim的代码)
到这里如果你认真阅读并思考后一定已经解决了你想问的问题了。
网硕互联帮助中心





评论前必须登录!
注册