C语言中的可变量参数宏和##说明

有时我们写程序可能会定义许多DEBUG模式下的调试打印信息宏来替代原有的打印函数,这时就会出现编写可变量参数宏的写法问题,下面就摘要性的写一下,运行及调试环境为rh linux 9.0+gcc 3.2.2

首先在gcc中,对可变量参数宏的支持要强的多,一般我们可以这么写:
#define MACRO_1(fmt, args…) printf(fmt, args)
#define MACRO_2(fmt, …) printf(fmt, VA_ARGS)
这两种写法都可以,后面一种是使用了关键字__VA_ARGS__,它代表宏中出现的…,而前面的写法就是给可变量的参数定义了一个名字,就是说在第一种写法中,args就是代表可变量参数,给出例子:
#include <stdio.h>
#define MACRO_1(fmt, args…) printf(fmt, args)
#define MACRO_2(fmt, …) printf(fmt, VA_ARGS)
int main()
{
MACRO_1(“MACRO_1:%s\n”, “Hello”);
MACRO_2(“MACRO_2:%s\n”, “Hello”);
return 0;
}
我们可以用gcc -E的参数来得到程序的宏展开源代码,主要部分如下:

int main()
{
printf(“MACRO_1:%s\n”, “Hello”);
printf(“MACRO_2:%s\n”, “Hello”);
return 0;
}
大家可以看到这里的对比.但有一个问题就是,如果我们只传递一个参数会怎么呢?也就是把源代码改写如下:
#include <stdio.h>
#define MACRO_1(fmt, args…) printf(fmt, args)
#define MACRO_2(fmt, …) printf(fmt, VA_ARGS)
int main()
{
MACRO_1(“MACRO_1\n”);
MACRO_2(“MACRO_2\n”);
return 0;
}
这样会不会有问题呢,我们看一下宏展开后的代码:
int main()
{
printf(“MACRO_1\n”, );
printf(“MACRO_2\n”, );
return 0;
}
这里多出现了一个",",问题的解决方法是在args和__VA_ARGS__前面加一个##,##表示去除它前面的",",但当我们传递多于一个参数的时候这也能工作,就像第一段代码一样,现在看一下加了##之后的代码及相应宏展开后的代码:
#include <stdio.h>
#define MACRO_1(fmt, args…) printf(fmt, ##args)
#define MACRO_2(fmt, …) printf(fmt, ##VA_ARGS)
int main()
{
MACRO_1(“MACRO_1\n”);
MACRO_2(“MACRO_2\n”);
return 0;
}
展开宏之后:
int main()
{
printf(“MACRO_1\n”);
printf(“MACRO_2\n”);
return 0;
}
问题解决了_
其实,##在c语言里功能不只是这个,它还可以起到连接两个变量的作用,看下面的代码:
#include <stdio.h>
#define UNION(a,b) (a##b)
int main()
{
char* long_long_var_prt = “Hello,world!”;
printf(“Test:\nSTR:%s\tNUM:%d\n”, UNION(long_, long_var_prt), UNION(10,8));
return 0;
}
这里开了一个小玩笑,就是把一个字符串的名字起得很长,然后再通过##把它们粘起来并输入,后面是把两个整数合并到一起,组成一个大的整数,展开宏之后的代码如下:
int main()
{
char* long_long_var_prt = “Hello,world!”;
printf(“Test:\nSTR:%s\tNUM:%d\n”, (long_long_var_prt), (108));
return 0;
}
输出如下:
Test:
STR:Hello,world! NUM:108

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值