C语言之 ## __VA_ARGS__ 宏

本文介绍了GNU C编译器(GCC)中的可变参数宏的定义与使用方法,包括宏的基本语法、如何通过__VA_ARGS__传递参数,以及如何避免预处理器展开时出现的错误。还展示了C99标准下可变参数宏的具体应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在GNU C中,宏可以接受可变数目的参数,就象函数一样。它允许你可以定义可变参数宏(variadic macros),这样你就可以使用拥有可以变化的参数表的宏。可变参数宏就像下面这个样子:

#define debug(...) printf(__VA_ARGS__)

缺省号代表一个可以变化的参数表。使用保留名 __VA_ARGS__ 把参数传递给宏。当宏的调用展开时,实际的参数就传递给 printf()了。

Debug( "Y = %d\n" , y);


而处理器会把宏的调用替换成:

1
printf ( "Y = %d\n" , y);
 
可变参数宏不被ANSI/ISO C++ 所正式支持。因此,你应当检查你的编译器,看它是否支持这项技术。

gcc的预处理提供的可变参数宏定义真是好用:

?
1
2
3
4
5
6
#ifdef DEBUG 
#define dbgprint(format,args...) \ 
fprintf (stderr, format, ##args) 
#else 
#define dbgprint(format,args...) 
#endif

如此定义之后,代码中就可以用dbgprint了,例如dbgprint("%s", __FILE__);

 

新的C99规范支持了可变参数的宏
具体使用如下:

以下内容为程序代码:

?
1
2
3
4
5
6
7
8
#include <stdarg.h> 
#include <stdio.h> 
#define LOGSTRINGS(fm, ...) printf(fm,__VA_ARGS__) 
int main() 
     LOGSTRINGS( "hello, %d " , 10); 
     return 0; 
}
 
 
GCC始终支持复杂的宏,它使用一种不同的语法从而可以使你可以给可变参数一个名字,如同其它参数一样。例如下面的例子:
?
1
#define debug(format, args...) fprintf (stderr, format, args)
 
在上面的例子中,编译器仍然会有问题(complain),因为宏展开后,里面的字符串后面会有个多余的逗号。

为了解决这个问题,CPP使用一个特殊的'##'操作。书写格式为:

?
1
#define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
果可变参数被忽略或为空,'##'操作将使预处理器(preprocessor)去除掉它前面的那个逗号
 
##还可以起到替换作用
如:
?
1
#define FUN(IName)  IName##_ptr


这里将会把IName变成实际数据.

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值