宏#、##、@、__VA_ARGS__基本使用

一、宏解释

1.#用来把参数转换成字符串

2.##:用于将带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串;但它不可以是第一个或者最后一个子串。所谓的子串(token)就是指编译器能够识别的最小语法.
3.__AV_ARGS__表示可变参数列表。
4.##__AV_ARGS__可用在无参数数去除前面的“,”否则当不传参时会报错。

二、使用步骤

例程1:验证“#”转换字符串功能

#include <stdio.h>
#define LOGS(x)       printf("%s--%d\r\n",#x,x);
int main()
{
     int a=10;
     LOGS(a);//测试#(参数转字符串)
     return 0;
}

运行结果:
a–10


例程2:验证“##”连接字符串功能

#include <stdio.h>
#define LOG(x)    out_##x()
void out_1(void)
{
     printf("This is out_1 \r\n");
}
void out_2(void)
{
     printf("This is out_2 \r\n");
}

int main()
{
     LOG(1) ;//测试## (拼接)
     return 0;
}

运行结果:
This is out_1


例程3:样可变参

代码如下(示例):

#include <stdio.h>
#define LOGV(...)       printf(__VA_ARGS__);

int main()
{
      int a=10,b=11;
      LOGV("a=%d--b=%d\r\n",a,b);//测试可变参
     return 0;
}

运行结果:
a=10–b=11


例程4:综合应用

#include <stdio.h>
#define LOG(module_str, msg, ...) printf("["module_str"][%s][%d] "msg"", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define INIT_LOG(msg, ...) LOG("init",msg, ##__VA_ARGS__)
int main()
{
      int a=10;
      INIT_LOG("%d\r\n",a);
      return 0;
}

运行结果:
[init][main][7] 10


例程5:验证##VA_ARGS中“##”作用

#include <stdio.h>
#define LOG( msg, ...) printf("[%s][%d] "msg"", __FUNCTION__, __LINE__,##__VA_ARGS__)
int main()
{
     int a=10;
     LOG("1234\r\n");//去除##VA_ARGS__中的##将会报错
     return 0;
}

运行结果:
[main][5] 1234
如果去除##VA_ARGS__中的##将会报错


例程6:验证@符作用

#@x会将x转换为字符 例如#@a等价于’a’;

#include <stdio.h>
#define symbo(x) #@x
int main()
{
     char buf=symbo(a);
     LOG("buf:%c\r\n",buf);//打印字符a
     return 0;
}

运行结果:
buf:a

总结

#define LOGV(...)       printf(__VA_ARGS__);
#define LOG( msg, ...) printf("[%s][%d] "msg"", __FUNCTION__, __LINE__,##__VA_ARGS__)
#define LOG( msg, ...) printf("[%s][%d] "msg"", __FUNCTION__, __LINE__,__VA_ARGS__)

第一条宏使用的__VA_ARGS__ 可进行变参 LOGV(“123\r\n”)、LOGV(“%d–%d\r\n”,a,b);这样的语句都可以进行打印。
第二条宏增加了__FUNCTION__及__LINE__宏可在调用时将所调用的函数及行号打印出来。同时一样支持LOGV(“123\r\n”)、LOGV(“%d–%d\r\n”,a,b);所有通用的打印。
第三条宏只支持LOGV(“%d–%d\r\n”,a,b);这样的带参数打印(至少一个参数),否则将会进行报错例如:LOGV(“123\r\n”),正如前面的说明##__ VA_ARGS__可去除前面参数的“,”因此##__ VA_ARGS__去除的不是调用参数的“,”而是宏声明时前面的参数的“,”如__FUNCTION__,__LINE__等。
当然在使用中如果可以把底层的printf两个参数颠倒过来,将__VA_ARGS__放到参数最前面我想应该也能实现使用__VA_ARGS__即可进行打印无参内容。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值