前段时候在实现利用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. js数组扁平化

    看到一个有趣的题目: var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; 一个多维 ...

  2. iTOP-iMX6UL开发板【全能版】-动态调频技术简介

    本文档以 iMX6UL 为例,简单介绍 cpufreq 的 5 种模式. 在 imx6ul 的 menuconfig 中,进入 CPU Power Management ---> CPU Fre ...

  3. window C/C++ 简单的IDE编译器

    C-Free 官网链接: http://www.programarts.com/cfree_ch/download.htm

  4. L1-Day15

    1.      我记得昨天锁门了呀.(什么关系?“记得”后面,如果接动词,那动词该是什么形式?) [我的翻译]I remembered locking the door yestarday. [标准答 ...

  5. Spring框架-IOC/DI详细学习

    一.IOC/DI概念 参考博客:https://www.cnblogs.com/xdp-gacl/p/4249939.html IOC(inversion of control, 控制反转)是一种设计 ...

  6. 项目Alpha冲刺(团队)-第二天冲刺

    格式描述 课程名称:软件工程1916|W(福州大学) 作业要求:项目Alpha冲刺(团队)-代码规范.冲刺任务与计划 团队名称:为了交项目干杯 作业目标:描述第二天冲刺的项目进展.问题困难.心得体会 ...

  7. TinyMCE

    段落段落段落段落 标题1 标题2 标题3 标题4 标题5 标题6

  8. webpack 打包报错:One CLI for webpack must be installed. These are recommended choices, delivered as separate packages

    webpack 打包报错: One CLI for webpack must be installed. These are recommended choices, delivered as sep ...

  9. Django-路由控制

    Django-路由控制 一.URL路由基础 URL是web服务的路口,用户通过浏览器发送过来的任何请求都会被发送到一个指定的URL地址里,然后被响应. 在django项目中编写路由就是向外暴露我们接收 ...

  10. form中的button默认提交事件

    <form action=""> <input autocomplete="off" type="text" name=& ...