宏定义中的可变参数 __VA_ARGS__ 用法 与 #和##的用法

首先了解一下可变参数

#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在这里,就修一下
先简单讲解一下宏定义,我们在宏定义的时候大体可以做这样的动作分解:

  1. 有括号参数就先把参数原原本本的传进去,比如DEBUG(8)里面的x=8,就把后面的x全部换成8
  2. 接着把宏定义后面的换过的内容放到宏定义的位置
    所以这里就有一个实际问题,很多时候我们为了用可变参数,都是把它加在我们想要的参数之后的,所以会在宏定义的最后一部分有一个逗号存在(参数一,参数二,可变参数)(就是那个第二个逗号),那这样万一我想要的是这次不用可变参数,可变参数为空,那内容是不是就变成了(参数一,参数二,),这样会产生报错。
  • 基于此,新的模式##__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");   // 正常运行

关于#和##

首先了解上面说的宏定义展开分解动作,这两个是在中间加了一步

  1. 有括号参数就先把参数原原本本的传进去,比如DEBUG(8)里面的x=8,就把后面的x全部换成8
  2. #是把他后面的内容转变为字符串,##是把他前后的东西连接成一个整体的标志符
  3. 接着把宏定义后面的换过的内容放到宏定义的位置

这两个东西其实应用的地方都非常特定

  • 对于#

    #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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值