可变参数__VA_ARGS__使用
1. 调试功能一般会使用到宏+可变参数的方式
1.1
##__VA_ARGS__ 之详细解析
例如:
case A.
#define my_print1(...) printf(__VA_ARGS__)
my_print1("i=%d,j=%d\n",i,j) 正确打印
case B.
#define my_print2(fmt,...) printf(fmt, __VA_ARGS__)
my_print1("i=%d,j=%d\n",i,j)
正确打印
my_print2("iiiiiii\n")
编译失败,因为扩展出来只有一个参数,至少要两个及以上参数
case C.
#define my_print2(fmt,...) printf(fmt, ##__VA_ARGS__)
my_print1里面不管是几个参数都能正确打印
宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的","去掉的作用,否则会编译出错
#define MODULE_NAME "MY_LIBS"
#define log_e(fmt, ...) printf("[ERROR]["MODULE_NAME"](%s|%d)"fmt,__func__,__LINE__,##__VA_ARGS__)
#include <stdio.h> #define MODULE_NAME "MY_LIBS" #define log_e(fmt, ...) printf("[ERROR]["MODULE_NAME"](%s|%d)"fmt,__func__,__LINE__, ##__VA_ARGS__) int main(){ int i = 1111; log_e("hello : i=%d\n", i); return 0;
}
root@lmw-virtual-machine:/home/lmw/桌面/C_Text#
root@lmw-virtual-machine:/home/lmw/桌面/C_Text# gcc my_log.c -o ab
root@lmw-virtual-machine:/home/lmw/桌面/C_Text#
root@lmw-virtual-machine:/home/lmw/桌面/C_Text# ./ab
[ERROR][MY_LIBS](main|14)hello : i=1111
root@lmw-virtual-machine:/home/lmw/桌面/C_Text#
1.2
#include <iostream>
#include <stdio.h>
using namespace std; #define Debug( fmt2, arg12... ) \
do{ printf("%s, %s %s\n", fmt2, ##arg12); \ // 这里有两个%s对应##arg12,所以就会打印出可变参数中的两个参数"what" 和"nice"
printf("***************[%s-%s-%d]: "fmt2 , __FILE__, __FUNCTION__, __LINE__, ##arg12); \
}while(0); int main(){ Debug("hi %s %s \n", "what", "nice"); // 针对这条打印进行分析 return 0;
} // 实测,第二条打印语句内的 "hi %s %s \n" 就是fmt2。
// 而"what", "nice"是不定参数##arg12的值
第二条打印语句分析: "hi %s %s \n"就是fmt2。 而"what", "nice"是不定参数##arg12的值。
需要注意的是: 如果只有1个%s格式符对应##arg12,那么只会打印出第一个"what",如果有两个格式符,那么则会打印出两个可变参数。
代码运行结果:
2. 编写一些功能函数的时候,我们也会用到可变参数
C++代码示例:
string combine_devtypes(int num, ...){ string ret, tmp;
va_list valist;
char* str = NULL;
int i; /* 为 num 个参数初始化 valist */
va_start(valist, num); /* 访问所有赋给 valist 的参数 */
for (i = 0; i < num; i++)
{
str = va_arg(valist, char*);
tmp = str;
ret += tmp; if(i < num-1){
tmp = " ";
ret += tmp;
}
} /* 清理为 valist 保留的内存 */
va_end(valist); return ret;
}
本例子的函数功能是拼接字符串,并且在中间加上一个空字符。
调用方式: string obj = combine_devtypes(2, "hello", "boy") , 得到的是包含"hello boy"信息的这么一个字符串。
.
可变参数__VA_ARGS__使用的更多相关文章
- 可变参数宏__VA_ARGS__和...
__VA_ARGS__ 是一个可变参数的宏(gcc支持).实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点).这样预定义宏_ _VA_ARGS_ _就可以被用在替换部分中,替换省略号所 ...
- 可变参数宏__VA_ARGS__
在 GNU C 中,宏可以接受可变数目的参数,就象函数一样,例如:#define pr_debug(fmt,arg...) \printk(KERN_DEBUG fmt,##arg) 用可变参数宏(v ...
- __VA_ARGS__可变参数宏
#define qWiFiDebug(format, ...) qDebug("[WiFi] "format" File:%s, Line:%d, Function:%s ...
- 可变参数宏...和__VA_ARGS__
__VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持).实现思想就是宏定义中参数列表的最后一个参数为 ...
- 【转】C,C++中使用可变参数
可变参数即表示参数个数可以变化,可多可少,也表示参数的类型也可以变化,可以是 int,double还可以是char*,类,结构体等等.可变参数是实现printf(),sprintf()等函数的关键之处 ...
- C语言可变参数在宏定义中的应用
在C语言的标准库中,printf.scanf.sscanf.sprintf.sscanf这些标准库的输入输出函数,参数都是可变的.在调试程序时,我们可能希望定义一个参数可变的输出函数来记录日志,那么用 ...
- [转载]用可变参数宏(variadic macros)传递可变参数表
注意:_VA_ARGS__ 从VS2005才开始支持 在 GNU C 中,宏可以接受可变数目的参数,就象函数一样,例如: #define pr_debug(fmt,arg...) printk(KER ...
- GNU C和C99标准中的可变参数宏(variadic macros)
用可变参数宏(variadic macros)传递可变参数表你可能很熟悉在函数中使用可变参数表,如: void printf(const char* format, …); 直到最近,可变参数表还是只 ...
- C++: 可变参数;
可变参数,即参数的个数是动态变化的, 可多可少. 1. 可变参数: 可变参数一般采用”..."表示,用在宏上表示变参宏, 如: #define WriteLine(format,...) p ...
随机推荐
- 2020重新出发,MySql基础,性能优化
@ 目录 MySQL性能优化 MySQL性能优化简述 使用 SHOW STATUS 命令 使用慢查询日志 MySQL 查询分析器 EXPLAIN DESCRIBE 索引对查询速度的影响 MySQL优化 ...
- unity坑-编译错误
问题: 项目里面有一个 StreamReader来读取一个文件,使用OpenText() 方法. 但是UNITY却提示 StreamReader类不包含OpenText()方法,并且也没有找到扩展方法 ...
- P1020 导弹拦截(nlogn求最长不下降子序列)
题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...
- 面试【JAVA基础】其他
1.自定义注解 @target 说明了Annotation所修饰的对象范围: constructor.method.field.package.type等等. @retention 定义了该Annot ...
- 下拉列表被flash覆盖的解决方法
做鼎闻有一段时间了,有的banner轮播图的地方用flash替换的时候,就会导致上面的导航条下拉列表被flash覆盖,找了一段时间没有得到有效的解决方法,后来知道关键是flash的这一属性{ &quo ...
- 【阿里云训练营】python查漏补缺 1
文章来自:微信公众号[机器学习炼丹术]. 有问题疑惑,或者想交流交朋友的可以加个人微信:cyx645016617 参考目录: 目录 1 注释 2 is 与 == 3 运算优先级 4 查找所有属性和方法 ...
- Jmeter4.0安装教程
1. 检查安装环境 1.1 Jdk要求 JDK版本:1.6+ 1.2 检查是否安装JDK win + R 快捷键打开运行,输入cmd 打开面板,在面板中输入 java -version,出现如 ...
- FIddlerd的下载教程和使用教程
------------恢复内容开始------------ .打开官网,官网下载地址是https://www.telerik.com/download/fiddler .打开以后选择你的相关信息如下 ...
- 操作BOM对象
操作BOM对象 目录 操作BOM对象 1. 浏览器介绍 2. window 3. Navigator(不建议使用) 4. screan 5. location(重要) 6. document(内容:D ...
- LongAccumulator类的BUG——reset方法并不能保证初始值正确赋值
LongAccumulator.reset方法并不能重置重置LongAccumulator的identity:初始值正确,使其恢复原来的初始值.当初始值为0是不会发生这个问题,而当我们设置初始值如1时 ...