前段时候在实现利用redis进行的一个数据库比对的功能,稍微去分析了一下redis里面的源代码,然后发现其中的发送命令接口声明如下:

void *redisCommand(redisConnect *c,const char * Format,...);

  其中使用了我以前没有见过的 "..." ,想起之前学习java视频的时候,好像提到过java的可变参数功能,于是就去网上查阅了一下,发现可变参数也是C语言提供的一个功能。

  关于功能的应用场景我举两个例子吧:

  第一个就是上面的这个函数声明,在redis中上面这个函数功能就是向指定的 redisconnect连接发送句柄的。redisconnect存的是redis连接的端口,Fromat存的指令句柄,后面的"..."则使得这个函数可以支持一次性传如多个指令:

reply = (redisReply *)redisCommand(context, cmd);

reply = (redisReply *)redisCommand(context, cmd, cmd2, cmd3);

  第一行代码,很容易理解,就是通过语句传入cmd句柄让redis执行cmd句柄中的语句。

  第二行代码,则让redis依次执行cmd,cmd1,cmd2三个句柄。

  在这个样例中,我们可以通过一个接口一次性传入未知的参数量,也可以避免重复调用接口、建立连接,或者要更新函数、重载函数。

  具体如何实现多个句柄传入我们不妨先看看场景二。

  第二个场景其实就更常见了,可以看一下我下面这段代码:

#include "cstdio"
#include "stdarg.h" void pt(const char* format, ...) {
int n;
va_list arg_list;
va_start(arg_list, format);
n = vprintf(format, arg_list);
va_end(arg_list);
} int main(){
pt("%d , %d , %d , %d\n",1,2,3,4);
return 0;
}

  输出之后,你就会发现,这个pt()函数和我们平常用的printf()函数实现的功能一样!

  是的,我们通过控制台读入和输出的scanf(),和printf()两个函数都使用了可变参数,这样也就解释了,为啥一个scanf()函数我们可以一次性输入不管多少个参数了。

  可变参数!

  C调用约定下可使用在stdarg.h这个头文件中的va_list系列变参宏实现变参函数,此处va意为variable-argument(可变参数)。

详情可以去博客进行了解:https://www.cnblogs.com/clover-toeic/p/3736748.html

  

  后面了解到在C++中使用可变参数有另外的一种方法:

void debug() {
cout << endl;
}
template<typename T, typename ...R> void debug (T f, R ...r) {
cout << " [" << f << "] ";
debug (r...);
}

  上面这段代码可以在控制台输出你传递到debug()中的所有变量,不过使用的理念和C语言版本的不同。

  C语言版本是把你传递进去的参数压入堆栈,然后用va_list系列的函数不断取出栈内的值。

  而上面这段C++的代码,使用递归每次输出第一个参数,简明易懂。

  虽然通常我们写代码一般是不会出现这种代码的,但是如果只是我们自己对代码进行debug的时候,这样写对我们进行debug无疑会更方便一点。

最新文章

  1. Android开机启动程序
  2. Golang友团无闻Go语言Web基础视频教程
  3. 二、Python 数据类型
  4. Integer Inquiry【大数的加法举例】
  5. 【BZOJ1864】[Zjoi2006]三色二叉树 树形DP
  6. delphi中Message消息的使用方法
  7. maven下载的jar文件出现invalid LOC header (bad signature)
  8. 基于Flume的美团日志收集系统(二)改进和优化
  9. Web 前端最佳实践
  10. jQuery moblie 配合jQuery 实现移动端下拉刷新
  11. VirtualBox的快照功能
  12. 十二、存token获取token刷新token发送header头
  13. go官方的http.request + context样例
  14. JSP(3)—Cookie和Session
  15. 12C新特性 -- 共享asm口令文件
  16. 在springboot中用redis实现消息队列
  17. hdu 5129 (枚举) The E-pang Palace
  18. lucene-01-简介
  19. c#版本与vs的对应关系
  20. 图解vim常用命令

热门文章

  1. 第30月第11天 Xcode 9.0中新增的API版本检查@available
  2. axios formData提交数据 &amp;&amp; axios设置charset无效???
  3. 【easy】141. Linked List Cycle
  4. 关于el-upload上传
  5. axios 拦截器统一在接口增加时间戳参数,防止走缓存。
  6. Nginx+IIS+asp.net mvc 实现负载均衡示例
  7. MiniGUI 如何显示繁体字
  8. 对Inode、Hard Link以及Soft Link的理解
  9. Log4j使用笔记:每天生成一个日志文件、按日志大小生成文件
  10. Python @property 详解