1 C语言中"##"的独特用法:胶水运算”(连接字符串的作用),用于把参数宏中的“形参”与其它没有天然分割的内容粘连在一起。
#define def_u32_array(__name, __size) uint32_t array_##__name[__size];
#define safe_atom_code(...) { uint32_t int_flag = __disable_irq(); /*将变参放到下面位置取代__VA_ARGS__*/ __VA_ARGS__ __set_PRIMASK(int_flag); } static __inline void wr_dat (uint_fast16_t dat) { safe_atom_code( LCD_CS(0); GLCD_PORT->DAT = (dat >> 8); /* Write D8..D15 */ GLCD_PORT->DAT = (dat & 0xFF); /* Write D0..D7 */ LCD_CS(1); ) }
/* ",##__VA_ARGS__",如果__VA_ARGS__是一个空字符串,则前面的","会一并被删除掉 */ #define log_info(__STRING, ...) printf(__STRING,##__VA_ARGS__) log_info("------------------------------------ "); log_info(" Cycle Count : %d", total_cycle_cnt); //展开后: printf("------------------------------------ ",);// ",##__VA_ARGS__被删除" printf(" Cycle Count : %d", total_cycle_cnt);
#define XXXX_INIT(...) xxxx_init((NULL,##__VA_ARGS__)) int xxxx_init(xxxx_cfg_t *cfg_ptr); XXXX_INIT() //cfg_ptr=NULL XXXX_INIT(pcfg) //cfg_ptr=pcfg
struct { uint16_t msg; uint16_t mask; int (*handler)(msg_t *msg_ptr); } msg_t; typedef struct msg_t msg_t; #define def_msg_map(__name, ...) const msg_t __name[] = {__VA_ARGS__}; #define add_msg(__msg, __handler, ...) { .msg = (__msg), .handler = &(__handler), .msk = (0xFFFF, ##__VA_ARGS__), } /*! ote 高字节表示操作的类别: 比如0x00表示控制类,0x01表示WRITE,0x02表示READ */ enum { SIGN_UP = 0x0001, WRITE_MEM = 0x0100, WRITE_SRAM = 0x0101, WRITE_FLASH = 0x0102, WRITE_EEPROM = 0x0103, READ_MEM = 0x0200, READ_SRAM = 0x0201, READ_FLASH = 0x0202, READ_EEPROM = 0x0203, }; extern int iap_sign_up_handler(msg_t *msg_ptr); extern int iap_write_mem(msg_t *msg_ptr); extern int iap_read_mem(msg_t *msg_ptr); def_msg_map( iap_message_map /* 严格的将 SIGN_UP 映射到 对应的处理函数中 */ add_msg( SIGN_UP, iap_sign_up_handler ), /* 批量处理所有的WRITE操作,使用掩码进行过滤*/ add_msg( WRITE_MEM, iap_write_mem, 0xFF00 ), /* 批量处理所有的READ操作,使用掩码进行过滤 */ add_msg( READ_MEM, iap_read_mem, 0xFF00 ), )
变参:__VA_ARGS__等于。。。增加缺省
#define SENSOR_Printf(...) printf("--SENSOR--"__VA_ARGS__) int TemperatureVal = 25; SENSOR_Printf("温度 = %d℃ ", TemperatureVal); --SENSOR--温度 = 25℃
__FILE__:正在编译文件的路径及文件名
__LINE__:正在编译文件的行号
__DATE__:编译时刻的日期字符串 如“July 19 2019”
__TIME__:编译时刻的时间字符串 如”22:00:00“
__FUNCTION__:函数名,类型为:字符常量指针
__VER__:IDE版本信息,类型为:整型
char BuildFile[] = __FILE__; int BuildLine = __LINE__; char BuildDate[] = __DATE__; char BuildTime[] = __TIME__; printf("编译文件路径:%s ", BuildFile); printf("编译代码所在行:%d ", TestLine); printf("编译日期:%s ", BuildDate); printf("编译时间:%s ", BuildTime);