文章目录
1,防止一个头文件被重复包含
#ifndef BODYDEF_H
#define BODYDEF_H
//头文件内容
#endif
2,得到指定地址上的一个字节或字
#define MEM_B( x ) ( *( (char* ) (x) ) )
#define MEM_W( x ) ( *( (short* ) (x) ) )
3,得到一个field在结构体(struct)中的偏移量
#define FPOS( type, field ) ( (int) &(( type *) 0)->field )
4,使用一些宏跟踪调试
_LINE_ (两个下划线),对应%d
_FILE_ 对应%s
_DATE_ 对应%s
_TIME_ 对应%s
#include <stdio.h>
#define debug(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
// __VA_ARGS__ 为("..."对应的内容)
int main(void)
{
// 输出为
// Dec 1 2021,05:12:28
debug("%s,%s\n", __DATE__, __TIME__);
return 0;
}
5,字符串化# 和 宏连接符##
6,常用于内核的填充结构相关代码
#define FILL(a) {a, #a}
enum IDD{OPEN, CLOSE};
typedef struct MSG{
IDD id;
const char * msg;
}MSG;
MSG _msg[] = {FILL(OPEN), FILL(CLOSE)};
// 相当于:
// MSG _msg[] = { {OPEN, "OPEN"}, {CLOSE, "CLOSE"} };
7,可变参数传递
- 1、
__VA_ARGS__
__VA_ARGS__
就是"..." 表示的内容
如
#define debug(format, ...) fprintf(stderr, fmt, __VA_ARGS__)
在GCC中也支持这类表示, 但是在G++ 中不支持这个表示.
例程
#include <stdio.h>
#define debug(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
// __VA_ARGS__ 为("..."对应的内容)
int main(void)
{
// 输出:Dec 1 2021,05:12:28
debug("%s,%s\n", __DATE__, __TIME__);
return 0;
}
- 2、GCC 的复杂宏
GCC使用一种不同的语法从而可以使你可以给可变参数一个名字,如同其它参数一样。
#define debug(format, args...) fprintf (stderr, format, args)
这和上面举的那个定义的宏例子是完全一样的,但是这么写可读性更强并且更容易进行描述。