常用宏定义
在编写代码的时候经常会用到一些宏定义,使用宏定义可以使我们的代码更加规范,而且使用选择类型的宏定义还可以使我们编写出来的代码更小,也更利于程序的移植与修改。
常用的一些宏定义有#define、#undef、#ifdef、#ifndef、#if、#elif、#else、#endif,还有一个找了好久才找到的defined,没错,这个前面没有加#。
#define 定义一个预处理宏
#undef 取消宏的定义
#if 编译预处理中的条件命令,相当于C语法中的if语句
#ifdef 判断某个宏是否被定义,若已定义,执行随后的语句
#ifndef 与#ifdef相反,判断某个宏是否未被定义
#elif 若#if, #ifdef, #ifndef或前面的#elif条件不满足,则执行#elif之后的语句,相当于C语法中的else-if
#else 与#if, #ifdef, #ifndef对应, 若这些条件不满足,则执行#else之后的语句,相当于C语法中的else
#endif #if, #ifdef, #ifndef这些条件命令的结束标志.
defined 与#if, #elif配合使用,判断某个宏是否被定义
使用方式
一、预编译
预编译一般使用的是#define,可以定义一些常量,也可以直接定义一个对象,或者是一个函数,与之相对应的就是#undef,就是将#define定义的宏定义进行取消,我一般在调试代码的时候会用到。
//#define
// 常量定义
#define MCU_ID_ADDR 0x1FFFF7AC
// 标识重定义
#define SYS_LED_Pin GPIO_PIN_3
// 预编译宏
#define _DEBUG
// 最小值函数
#define MIN(a,b) ((a)>(b)? (a):(b))
//#undef可以取消宏定义,与#define对应
// 预编译宏
#undef _DEBUG
二、条件编译
1、使用#ifdef和#endif来灵活定义变量,注意每个#ifdef后面都必须有一个#endif结尾
//hal库中定义包含.h文件的宏定义
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32f4xx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifndef使用方式类似
//定义头文件常用的方式
#ifndef __STM32F4xx_HAL_CONF_H
#define __STM32F4xx_HAL_CONF_H
#endif
2、#ifdef、#ifndef、#else、#endif
条件编译中相对常用的预编译指令
#ifdef ABC
// ... codes while definded ABC
#elif (CODE_VERSION > 2)
// ... codes while CODE_VERSION > 2
#else
// ... remained cases
#endif // #ifdef ABC
#ifndef使用方式类似,这里就不举例了
3、#if、#elif、#else、#endif
#if可支持同时判断多个宏的存在,与常量表达式配合使用
#if 常量表达式1
// ... some codes
#elif 常量表达式2
// ... other codes
#elif 常量表达式3
// ...
...
#else
// ... statement
#endif
常量表达式可以是包含宏、算术运算、逻辑运算等等的合法C常量表达式,如果常量表达式为一个未定义的宏, 那么它的值被视为0
在判断某个宏是否被定义时,应当避免使用#if,因为该宏的值可能就是被定义为0。而应当使用#ifdef或#ifndef。
#ifdef __cplusplus
extern "C" {
#endif
注意: #if、#elif之后的宏只能是对象宏。如果宏未定义,或者该宏是函数宏,则编译器可能会有对应宏未定义的警告。
4、defined
defined用来测试某个宏是否被定义。defined(name): 若宏被定义,则返回1,否则返回0。
它与#if、#elif、#else结合使用来判断宏是否被定义,乍一看好像它显得多余, 因为已经有了#ifdef和#ifndef。defined可用于在一条判断语句中声明多个判别条件;#ifdef和#ifndef则仅支持判断一个宏是否定义。
#define STM31F4
#if defined STM32F0
#define MCU_ID_ADDR 0x1FFFF7AC
#elif defined STM32F1
#define MCU_ID_ADDR 0x1FFFF7E8
#elif defined STM32F2
#define MCU_ID_ADDR 0x1FFF7A10
#elif defined STM32F3
#define MCU_ID_ADDR 0x1FFFF7AC
#elif defined STM32F4
#define MCU_ID_ADDR 0x1FFF7A10
#elif defined STM32F7
#define MCU_ID_ADDR 0x1FF0F420
#elif defined STM32L0
#define MCU_ID_ADDR 0x1FF80050
#elif defined STM32L1
#define MCU_ID_ADDR 0x1FF80050
#elif defined STM32L4
#define MCU_ID_ADDR 0x1FFF7590
#elif defined STM32H7
#define MCU_ID_ADDR 0x1FF0F420
#endif
还有就是在defined前面加一个!的,表示没有定义,和取反的意思一样
#if !defined (HSE_VALUE)
#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */