前段时候在实现利用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. Apple Tree POJ - 2486 (树形dp)

    题目链接: D - 树形dp  POJ - 2486 题目大意:一颗树,n个点(1-n),n-1条边,每个点上有一个权值,求从1出发,走V步,最多能遍历到的权值 学习网址:https://blog.c ...

  2. Jmeter、Postman 、 loadrunner SoapUI 接口测试工具

    一. loadrunner  简称 LR 二. Jmeter 1.安装包:apache-jmeter-4.0.tgz   解压.学会此工具的使用  和POSTman 一样的. 2.本机测试:双击apa ...

  3. windows下Qt5.1 for android开发环境配置

    1.下载安装Qt 5.1.0 for Android (Windows 32-bit, 716 MB)   http://qt-project.org/downloads 2.打开Qt Creator ...

  4. requests使用retry策略

    在urllib3中使用retry 在requests中使用retry 网络请求往往会有很多不受控制的意外情况发生,有时候我们要让它let it crash,有时候我们想多尝试几次. 以前,使用retr ...

  5. 二十三种设计模式之原型模式的C#实现

    原型模式就是通过拷贝快速创建一个新的对象 本例UML如图 ColorBase [Serializable] public abstract class ColorBase { public int R ...

  6. [Linux]标准IO全缓冲和行缓冲

    概述 标准IO中,标准错误是不带缓冲的.若是指向终端设备的流才是行缓冲的,否则是全缓冲的. 行缓冲也可以分配缓冲区,当遇到超大行(超过缓冲区的行),缓冲区内容也会优先刷出. 示例 #include & ...

  7. 关于form-checkbox 必填项无效的错误

    校验规则要写在一个form里 检查data,给个默认值. 否则刚进去错误提示不显示. 其次,要加 type 类型,注意大小写 触发类型为 change .

  8. 小程序 movable-view 在页面中的可移动图标

    项目中需要一个可拖动的小图标, 1.小程序组件movable-view 文档地址:https://developers.weixin.qq.com/miniprogram/dev/component/ ...

  9. Spring出现事务代理的原因

    JdbcTemplate 在配置事务代理之前,JdbcTemplate 的关闭策略,就是操作完立刻关闭!意味着,默认情况是JdbcTemplate操作是不支持事务的!!! 但是我们的程序是需要支持事务 ...

  10. 马拉车算法——边界拓展时加限制hdu4513

    #include<bits/stdc++.h> using namespace std; #define maxn 500005 int n,p[maxn],s[maxn],s_new[m ...