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"信息的这么一个字符串。

.

最新文章

  1. 面试题12:打印1到最大的n位数
  2. jQuery in action 3rd - Working with properties, attributes, and data
  3. esriSRGeoCS3Type Constants
  4. Codeforces Round #181 (Div. 2) A. Array 构造
  5. having与where区别
  6. 关于@see注解
  7. 【实习记】2014-08-23网络安全XSS与CSRF总结
  8. C++/C# 开发高级案例资料一次送!关注加群领取哦!
  9. Charles手机抓包常见问题(各种常见坑)
  10. 如何 dump jvm 内存及线程栈
  11. Spark学习(一)
  12. ASP.NET MVC不可或缺的部分——DI及其本质工作分析
  13. 机器学习实战1-2.1 KNN改进约会网站的配对效果 datingTestSet2.txt 下载方法
  14. js 把一个对象赋值给另一个对象会指向同一个内存地址
  15. C# OpenFileDialog打开文件对话框(详解)
  16. github贡献开源项目
  17. Word 如何实现表格快速一分为二
  18. C++中关键字explicit的作用
  19. PHPCMS源码分析
  20. java中常用Redis操作

热门文章

  1. 如何通过seo技术提高网站对用户的友好度
  2. 3个必备cookie实用方法
  3. redis数据库基础篇
  4. 透过UIRoot深入理解NGUI提供的屏幕适配方案
  5. react native 常用学习或查资料网址
  6. 【原】“Error getting &#39;android:label&#39; attribute”
  7. 【HttpRunner v3.x】笔记 ——4. 测试用例-结构解析
  8. CodeForces - 505B-Mr. Kitayuta&#39;s Colorful Graph(暴力)
  9. map 地图组件
  10. 20190923-11Linux crond 系统定时任务 000 019