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__使用的更多相关文章

  1. 可变参数宏__VA_ARGS__和...

    __VA_ARGS__ 是一个可变参数的宏(gcc支持).实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点).这样预定义宏_ _VA_ARGS_ _就可以被用在替换部分中,替换省略号所 ...

  2. 可变参数宏__VA_ARGS__

    在 GNU C 中,宏可以接受可变数目的参数,就象函数一样,例如:#define pr_debug(fmt,arg...) \printk(KERN_DEBUG fmt,##arg) 用可变参数宏(v ...

  3. __VA_ARGS__可变参数宏

    #define qWiFiDebug(format, ...) qDebug("[WiFi] "format" File:%s, Line:%d, Function:%s ...

  4. 可变参数宏...和__VA_ARGS__

    __VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持).实现思想就是宏定义中参数列表的最后一个参数为 ...

  5. 【转】C,C++中使用可变参数

    可变参数即表示参数个数可以变化,可多可少,也表示参数的类型也可以变化,可以是 int,double还可以是char*,类,结构体等等.可变参数是实现printf(),sprintf()等函数的关键之处 ...

  6. C语言可变参数在宏定义中的应用

    在C语言的标准库中,printf.scanf.sscanf.sprintf.sscanf这些标准库的输入输出函数,参数都是可变的.在调试程序时,我们可能希望定义一个参数可变的输出函数来记录日志,那么用 ...

  7. [转载]用可变参数宏(variadic macros)传递可变参数表

    注意:_VA_ARGS__ 从VS2005才开始支持 在 GNU C 中,宏可以接受可变数目的参数,就象函数一样,例如: #define pr_debug(fmt,arg...) printk(KER ...

  8. GNU C和C99标准中的可变参数宏(variadic macros)

    用可变参数宏(variadic macros)传递可变参数表你可能很熟悉在函数中使用可变参数表,如: void printf(const char* format, …); 直到最近,可变参数表还是只 ...

  9. C++: 可变参数;

    可变参数,即参数的个数是动态变化的, 可多可少. 1. 可变参数: 可变参数一般采用”..."表示,用在宏上表示变参宏, 如: #define WriteLine(format,...) p ...

随机推荐

  1. 网站SEO优化技术转让奇人

    http://www.wocaoseo.com/thread-111-1-1.html 本月假期我排到了今天星期二,由于工作性质原因经常会熬夜,养成一种不好的习惯"睡懒觉"视为享受 ...

  2. MySQL锁这块石头似乎没有我想的那么重

    前言 前言为本人写这篇文章的牢骚,建议跳过不看.   之前好几次都想好好的学习MySQL中的锁,但是找了几篇文章,看了一些锁的类型有那么多种,一时间也没看懂是什么意思,于是跟自己说先放松下自己,便从书 ...

  3. 浅谈 FTP、FTPS 与 SFTP

    无论是网盘还是云存储,上传都是一项很简单的操作.那些便捷好用的上传整理工具所用的 FTP 协议到底是什么意义,繁杂的模式又有何区别? 二狗子最近搭建了一个图片分享网站,每天都有好多人在他的网站上传许多 ...

  4. [] !== [] is true

    这周工作看见一个小伙伴给我私信发了这样的一个问题,我深剖了一下,希望大家能早点脱掉这个坑. Question: 如果定义了一个空数组,在开发过程中经常会做这样的一个判断,就是这个数组里发生变化不再是空 ...

  5. Auto Generate Reflection Information for C++

    https://www.reddit.com/r/gamedev/comments/3lh0ba/using_clang_to_generate_c_reflection_data/ https:// ...

  6. windows环境下利用Gitblit搭建Git服务器并实现自动部署Web站点目录

    Git服务搭建多见于linux环境,但windows主机也不少,目前网上文章诸多不全,且以讹传讹,不甚清楚.下面介绍windows环境下的自动部署和发布. 所需环境及资源:Java环境.Gitblit ...

  7. 条件竞争(race condition)

    条件竞争漏洞是一种服务器端的漏洞,由于服务器端在处理不同用户的请求时是并发进行的,因此,如果并发处理不当或相关操作逻辑顺序设计的不合理时,将会导致此类问题的发生. 参考了一些资料,发现一个比较能说明问 ...

  8. JavaScript 的 this 指向和绑定详解

    JavaScript 中的 new.bind.call.apply 实际这些都离不开 this,因此本文将着重讨论 this,在此过程中分别讲解其他相关知识点. 注意: 本文属于基础篇,请大神绕路.如 ...

  9. XmlAnalyzer1.00 源码

    此工程用途:将xml同级属性/子节点按字母序排列重新输出. 源码下载: https://files.cnblogs.com/files/heyang78/XmlAnalyzer-20200526-1. ...

  10. 【NOIP2013模拟】黑魔法师之门

    题目描述 经过了16个工作日的紧张忙碌,未来的人类终于收集到了足够的能源.然而在与Violet星球的战争中,由于Z副官的愚蠢,地球的领袖applepi被邪恶的黑魔法师Vani囚禁在了Violet星球. ...