首先了解一下可变参数
#include <stdio.h>
#define DEBUG(fmt, ...) printf(fmt, __VA_ARGS__)
int main(){
DEBUG("you know i am handsome%d,%f,%d", 1000, 1.1, 10);
return 0;
}
输出:
you know i am handsome1000,1.100000,10
这里的__VA_ARGS__其实就是指代…三个省略号的内容了,这就是这个结构的主体内容,基本已经成功了解了。
PLUS
然后程序在使用的时候会有一些健壮性的增强,修修边角了
1 命名(简单)
首先是命名,__VA_ARGS__有点难写所以产生了新的写法
#define LOG(format, args...) printf(format, args)
很明确了,就是一种简写而已。
2 修BUG
有一个比较大的BUG在这里,就修一下
先简单讲解一下宏定义,我们在宏定义的时候大体可以做这样的动作分解:
- 有括号参数就先把参数原原本本的传进去,比如DEBUG(8)里面的x=8,就把后面的x全部换成8
- 接着把宏定义后面的换过的内容放到宏定义的位置
所以这里就有一个实际问题,很多时候我们为了用可变参数,都是把它加在我们想要的参数之后的,所以会在宏定义的最后一部分有一个逗号存在(参数一,参数二,可变参数)(就是那个第二个逗号),那这样万一我想要的是这次不用可变参数,可变参数为空,那内容是不是就变成了(参数一,参数二,),这样会产生报错。
- 基于此,新的模式##__VA_ARGS__ ,这个东西和前面那个东西用法一样,修了BUG在没有可变参数的时候顺手去掉前面的逗号,上代码
#define DEBUG(fmt, ...) printf(fmt, __VA_ARGS__)
DEBUG("you know i am handsome");
#define DEBUG(fmt, ...) printf(fmt, ##__VA_ARGS__)
DEBUG("you know i am handsome");
第一个报错第二个正确执行。over
关于#和##
首先了解上面说的宏定义展开分解动作,这两个是在中间加了一步
- 有括号参数就先把参数原原本本的传进去,比如DEBUG(8)里面的x=8,就把后面的x全部换成8
- #是把他后面的内容转变为字符串,##是把他前后的东西连接成一个整体的标志符
- 接着把宏定义后面的换过的内容放到宏定义的位置
这两个东西其实应用的地方都非常特定
-
对于#
#define SQ(x) printf("The square of " #x " is %d.\n", ((x)*(x)));
SQ(8)
输出:
The square of 8 is 64
本来是int的8被转变为string然后直接在printf里面输出
-
对于##
#define XN(n) x ## n
int x1 = 10;
printf("%d\n", XN(1));
输出:
10
##就把x和1连在一起变成了一个标志符x1
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)