不管用什么语言编写程序,都会用到一些灵活的、简约的风格来实现简单的应用。C语言(当然也包括其他语种),设计良好的宏定义,不但可以使代码易懂耐用,而且也能大幅度提升自己对语言的掌控和应用能力,使得“面前的”代码量更少,实现的功能却不随之减少。不过,必须有度和并且具备极强的掌控力。
1、防止头文件被重复包含(写代码必须注意也是最基本的一点)
1 #ifndef _HEADER_FILE_H_ 2 #define _HEADER_FILE_H_ 3 4 /* Some contents of your header file */ 5 6 #endif
2、使用C++编译器编译C程序
在Linux下,不只有使用C语言编程的可能,也存在使用C++编程的时候,那么当C++工程中内嵌C(可能是推翻之前的C工程的决心不够,或者其他)的时候,关联C编译器会是比较好的选择。只需要在现在的C++工程头文件中包含下面的构建,即可:
#ifndef _HEADER_FILE_H_ #define _HEADER_FILE_H_ #ifdef __cplusplus__ extern "C"{ #endif /* Some contents of your header file */ #ifdef __cplusplus__ } #endif #endif
3、获取指定内存地址的内容
1 #define MEM_B(x) (*((byte *)(x))) //获取指定内存地址的一个字节 2 #define MEM_W(x) (*((word *)(x))) //获取指定内存地址的一个字
4、指定结构体中特定域的偏移量
1 #define FPOS(type,field) ((dword)&((type *)0)->field)
5、指定结构体中特定域的占用字节
1 #define FSIZE(type, field) sizeof(((type *)0)->field)
6、取指定变量的地址
1 #define B_PTR(var) ((byte *)(void *)&(var)) 2 #define W_PTR(var) ((word *)(void *)&(var))
7、避免在自增运算中造成溢出的可能
1 #define INC_SAT(val) (val=((val)+1 > (val)) ? (val)+1 : (val))
8、字母的大小写转换
1 #define UPCASE(c) (((c)>='a' && (c)<='z') ? ((c)-0x20) : (c)) 2 #define UPCASE(c) (((c)>='a' && (c)<='z') ? ((c)-0x20) : (c))
9、计算数组元素的个数
1 #define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
10、进制检测
1 #define DECCHECK(c) ((c)>='0' && (c)<='1') //二进制检测 2 #define DECCHECK(c) ((c)>='0' && (c)<='7') //八进制检测 3 #define DECCHECK(c) ((c)>='0' && (c)<='9') //十进制检测 4 #define HEXCHECK(hex) (((hex)>='0' &&(hex)<='9')||((hex)>='A' && (hex)<='F')||((hex)>='a' && (hex)<='f')) //十六进制检测
11、使用特定宏的跟踪调试
1 __LINE__ //程序运行所在的行号 2 __FILE__ //程序运行所在的文件名 3 __DATE__ //程序运行时间:月、日、年 4 __TIME__ //程序运行时间:时、分、秒 5 __FUNC__ //程序运行所在的函数体 6 /* printf("Function %s, Line %d in File %s\n", __FUNC__, __LINE__, __FILE); */
12、“#”和“##”的用法
12.1 记录文件名
1 #define _GET_FILE_NAME(f) #f 2 #define GET_FILE_NAME(f) _GET_FILE_NAME(f) 3 4 static char FILE_NAME[] = GET_FILE_NAME(__FILE__); 5 /* 成功后,可获得当前运行文件的文件名 */
12.2 结构填充
1 #define FILL(a) {a, #a} 2 3 enum IDD{OPEN, CLOSE}; 4 typedef struct MSG{ 5 IDD id; 6 const char * msg; 7 }MSG; 8 9 MSG _msg[] = {FILL(OPEN), FILL(CLOSE)}; 10 11 /* 成功后,MSG msg[] = {{OPEN,"OPEN"},{CLOSE,"CLOSE"}}; */
12.3 分配一个数值串形式大小的存储空间
1 #define _TYPE_BUF_SIZE(type) sizeof #type 2 #define TYPE_BUF_SIZE(type) _TYPE_BUF_SIZE(type) 3 4 char buf[TYPE_BUF_SIZE(INT_MAX)]; 5 /* INT_MAX,在<climit.h>中定义,大小是:0x7FFFFFFF,成功后,可获得:buf[11]的空间。 */
13、最大值和最小值
1 #define MAX(x, y) (((x) > (y)) ? (x) : (y)) 2 #define MIN(x, y) (((x) < (y)) ? (x) : (y))