前段时候在实现利用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无疑会更方便一点。

C语言可变参数的更多相关文章

  1. 转:C语言 可变参数

    C语言 可变参数 堆栈一般是怎么压栈处理的 /* * stack space: * *        参数3   |    up *        参数2   | *        参数1   v   ...

  2. C语言 可变参数

    一.基础部分 1.1 什么是可变长参数 可变长参数:顾名思义,就是函数的参数长度(数量)是可变的.比如 C 语言的 printf 系列的(格式化输入输出等)函数,都是参数可变的.下面是 printf ...

  3. C语言可变参数函数实现原理

    一.可变参数函数实现原理 C函数调用的栈结构: 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈. 本 ...

  4. 深入C语言可变参数(va_arg,va_list,va_start,va_end,_INTSIZEOF)

    一.什么是可变参数 在C语言编程中有时会遇到一些参数个数可变的函数,例如printf(),scanf()函数,其函数原型为: int printf(const char* format,…),int ...

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

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

  6. C语言可变参数函数的编写

    1. 引言 C语言我们接触的第一个库函数是 printf(“hello,world!”);其参数个数为1个. 然后,我们会接触到诸如: printf(“a=%d,b=%s,c=%c”,a,b,c);此 ...

  7. C语言可变参数va_list

    一.什么是可变参数 在C语言编程中有时会遇到一些参数个数可变的函数,例如printf(),scanf()函数,其函数原型为: int printf(const char* format,-) int ...

  8. c语言可变参数函数

    c语言支持可变参数函数.这里的可变指,函数的参数个数可变. 其原理是,一般情况下,函数参数传递时,其压栈顺序是从右向左,栈在虚拟内存中的增长方向是从上往下.所以,对于一个函数调用 func(int a ...

  9. Go语言 可变参数

    最近与同事讨论时,提到Go语言的可变参数,之前没有总结过相关知识点,今天我们介绍一下Go语言的可变参数. 可变参数(Variable Parameters):参数数量可变的函数称之为可变参数函数,主要 ...

随机推荐

  1. 97w网站邀请码

    我是一个老粉丝了. 如果想要97w网站邀请码可以留下联系方式,给我发过去哦. 最好是邮箱. http://www.97w.net/tag.html

  2. C#调用Bartender打印

    BarTender是一款优秀的条形码打印软件,可以支持很多种类型的条形码设计和打印,具体大家可参考他的官网(http://www.seagullscientific.com/aspx/products ...

  3. mvc RedirectToAction、mobile 重定向地址栏未改变

    @using (Html.BeginForm("actionName", "controllerName", FormMethod.Post, new { da ...

  4. sonar6.7.2启动报错

    sonar6.7.2启动报错:错误信息如下: es.log java.lang.RuntimeException: can not run elasticsearch as rootsonar.log ...

  5. 如何做一个项目.ppt

    链接:https://pan.baidu.com/s/1q8Ogj0xYQV_vk-HGcszxqw 提取码:0a82 复制这段内容后打开百度网盘手机App,操作更方便哦

  6. C# - 设计模式 - 模板模式

    模板模式 问题场景 咖啡和茶派生于抽象类饮料,咖啡和茶都具有烧水的方法,所以可以将烧水的方法提取到抽象类饮料中去实现,而咖啡具有一个向杯子加咖啡粉的方法,茶具有一个向杯子加茶叶的方法,看起来两个方法是 ...

  7. @Autowired和@Resource注解的一个意外重要区别

    今天上午,因为公司要跟客户展示最近开发的项目,然后安排了我重新构建一个template项目,用来向客户展示参考.基于已开发好的代码,我在进行一些简化抽取的时候出现了一个有趣的问题 因为我们有一个spr ...

  8. mac配置变量失败导致ls命令都失效

    1.在命令行中输入 export PATH=/usr/bin:/usr/sbin:/bin:/sbin:/usr/X11R6/bin 这样可以保证命令行命令暂时可以使用.命令执行完之后先不要关闭终端 ...

  9. CentOS6.5 下在Nginx中添加SSL证书

    原文:https://www.cnblogs.com/wuling129/p/5039978.html 证书过期 ,更新证书,记录下 一.安装相关支持库:(未实践) yum -y install gc ...

  10. 爬虫 selenium+Xpath 爬取动态js页面元素内容

    介绍 selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如 ...