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,可变参数传递

  • __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;
}

上面例程中,
debug(fmt, ...) 既可以输出指定内容,如 debug("666");;此时 … 所指代的内容为空
也可以格式化输出内容:debug("%s,%s", __DATE__, __TIME__);

还有一种 gcc 下的可变参数传递

#define pr_info(fmt, arg...) \
		printk(KERN_INFO fmt, ##arg)

例程如下:

#include <stdio.h>

#define pr1(fmt, arg...) \
        printf(fmt, ##arg)

#define pr2(fmt, ...) \
        printf(fmt, ##__VA_ARGS__);

int main(void)
{ 
    printf("%s(%d):\n", __FILE__, __LINE__);
    pr1("%d\n", 666666);
    pr2("%d\n", 88888888);
    printf("%s(%d):\n", __FILE__, __LINE__);
    return 0;
}

编译运行:

jl@jl-virtual-machine:~/test$ ./a.out 
test.c(11):
666666
88888888
test.c(14):
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值