C语言_01_宏定义使用技巧

来源:互联网 发布:python画热点图 编辑:程序博客网 时间:2024/06/03 05:53

对于底层软件开发的工程师, 对宏定义肯定不陌生吧, 我在写代码的时候就习惯使用宏定义, 代码结构清晰, 修改也及其便捷, 在以下场景时使用宏定义的优势.

1. 防止头文件被重复包含

#ifndef MAIN_H#define MAIN_H.....    //代码部分, 一般为全局变量, 函数声明#endif

2. 简单函数实现

#define ABS(x) ((x)>=0 ? (x):(-x);)  //取绝对值#define ADD(x,y) ((x)+(y))   //加法 #define MAX(x,y) ((x)>(y) ? (x):(y))  //最大值

3. 获取变量地址

#define PTR(var) ((UINT32*)(void*)&(var))

4. 字节拼字/字拆字节

#define BYTE_TO_WORD(ray) ((word)((ray)[0]*256)+(ray)[1])  //字节拼字 LSB方式#define WORD_TO_BYTE(ray,val)    \        (ray)[0] = ((val)/256);  \        (ray)[1] = ((val) & 0xFF)       //字拆字节

5. 类型重定义, 使代码跨平台和编译器

typedef unsigned char      UINT8;typedef signed char        INT8;typedef unsigned short     UINT16; typedef signed short       INT16;  typedef unsigned long int  UINT32; typedef signed long int    INT32;  typedef UINT8              BOOL;

6. 获取成员在结构体中的偏移/所占字节数

#define MEM_OFF(type, field)  (((UINT32)&(type *)0)->field)   //偏移#define MEM_SIZE(type, field)  (sizeof(type *)0)->field) //所占字节数

7. 获取指定地址上的字节/半字/字

#define ADDR_BYTE(x)  (*(UNIT8*)(x))      //字节#define ADDR_BYTE(x)  (*(UNIT16*)(x))     //半字#define ADDR_WORD(x)  (*(UINT32*)(x))     //字

8. 大小写转换

#define WORD_LOW(c)  ((c)>='A' && (c)<='Z') ? ((c)+0x20) : (c))#define WORD_UP(c)  ((c)>='a' && (c)<='z') ? ((c)-0x20) : (c))

9. 检查是否是十进制/十六进制

#define DEC_CHK(c)  ((c)>='0' && (c)<='9')   //十进制#define HEX_CHK(c)  ((c)>='0' && (c)<='9') ||   \                    ((c)>='A' && (c)<='F') ||   \                    ((c)>='a' && (c)<='f')   //十六进制

10. 获取半字的高低位

#define WORD_LO(c) (UINT8) ((UINT16)(c) & 0xFF))   //低8位#define WORD_HI(c) (UINT8) ((UINT16)((c)>>8) & 0xFF))   //高8位

11. 结构体初始化

typedef struct          //结构体定义{    uint16_t prescaler;          /**< Prescaler. */    uint8_t  interrupt_priority; /**< Interrupt priority. */    uint8_t  tick_latency;       /**< Maximum length of interrupt handler in ticks (max 7.7 ms). */    bool     reliable;           /**< Reliable mode flag. */} nrf_drv_rtc_config_t;#define NRF_DRV_RTC_DEFAULT_CONFIG                                                               \      //使用宏初始化结构体成员变量{                                                                                                \    .prescaler          = RTC_FREQ_TO_PRESCALER(RTC_DEFAULT_CONFIG_FREQUENCY),                   \    .interrupt_priority = RTC_DEFAULT_CONFIG_IRQ_PRIORITY,                                       \    .reliable           = RTC_DEFAULT_CONFIG_RELIABLE,                                           \    .tick_latency       = RTC_US_TO_TICKS(NRF_MAXIMUM_LATENCY_US, RTC_DEFAULT_CONFIG_FREQUENCY), \}static nrf_drv_rtc_config_t const m_rtc_config = NRF_DRV_RTC_DEFAULT_CONFIG;

12. 防止溢出

#define OVERFLOW(val) (val = ((val)+1 > (val)) ? (val)+1 : (val))

13. 求数组元素个数

#define ARR_NUM(a) ((sizeof(a)/sizeof(a[0]))

14. 求最接近的倍数值 //常用于内存分配

#define POWER8(x) ((((x)+7)/8)*8)

15. 用于跟踪调试 //ANSI标准(仅限于标准编译器, 非标准编译器可能支持不全或不支持)

__LINE__     //对应 %d    表示当前指令所在行, 是个整型数__FILE__     //对应 %s    表示当前指令所在文件, 包含完整路径 __DATE__     //对应 %s    包含形式为月/日/年的字符串, 表示源文件被翻译到代码时的日期__TIME__     //对应 %s    包含源代码翻译到目标代码的时间, 字符串形式为 时:分:秒__STDC__     //含有十进制常量1, 如果它含有任何其它数,则实现是非标准的

16. 调试使用

#ifdef __DEBUG    #define DEBUG_MSG(msg, date)  printf(msg);  printf("%d%d%d", date, __LINE__, __FILE__)#else    #define DEBUG_MSG(msg, date)

17. 防止多次初始化(只能进行一次)

#define NRF_LOG_INTERNAL_FLUSH()            \    do {                                    \        while (NRF_LOG_INTERNAL_PROCESS()); \    } while (0)
原创粉丝点击