c语言,宏相关

文章目录

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)

这和上面举的那个定义的宏例子是完全一样的,但是这么写可读性更强并且更容易进行描述。

上一篇:跳跳跳跳跳


下一篇:江西的省赛