C语言变参使用
来源:互联网 发布:java爬虫代码视频教程 编辑:程序博客网 时间:2024/06/08 14:03
C语言变参使用
C语言中有很多变参的使用,例如printf()的原型是int printf(const char *fmt, ...),那么C语言是如何解析和处理这些变参的呢?下面进行简单的总结:
C语言中定义了下面的一些宏,专门用来处理变参:
va_start(va_list ap, char *fmt)
va_arg(va_list ap , Type) //Type是指参数的类型(比如int、char*、double)
va_end(va_list ap)
从上面三个宏可以看到,它们都有一个va_list类型的参数,那么va_list是什么呢?如何定义的呢?
typedef char* va_list;可以看到va_list其实就是char*
下面继续解析上面的三个宏:
- va_start(va_list ap, char*fmt)
其中ap是va_list类型的,即可变参数列表;而fmt就是printf等类似函数的参数,指明参数的类型等,例如常见的有:%d%s%c%f等等
va_list()操作进行后的效果是:使得ap指向fmt后面的参数列表,即"...".C语言函数参数是从右向左压栈的
这个操作要在其他两个操作前面执行
- va_arg(va_list ap, Type)
在执行完va_start()操作后,ap就指向了变参的列表,这个时候就可以对变参列表进行操作了,是通过对ap进行操作实现的,因为此时ap指向变参列表
va_arg(va_list ap, Type)的结果是这样的:执行完这个操作后,首先返回ap当前指向的参数;然后ap向后移动,执行下一个参数;因此va_arg()是要循环调用的,直到所有参数都获得
Type是当前参数的类型
- va_end(va_list ap)
当上面操作进行完后,ap不再使用了,需要调用va_end()操作将ap给清空
根据上面的描述,在C语言中处理变参的过程大概是这样的:
- 定义va_list 变量,用来指向参数列表
- 调用va_start()操作,将定义的va_list变量指向变参列表
- 调用va_arg()操作,获得每个参数
- 调用va_end()操作,清空va_list变量
从上面的过程可以看到,在执行第三步的时候有点麻烦,比如事先根本不知道参数的类型等,这样调用va_arg()就不太方便了;而在实际中这样的现象是很多的,可以采用下面的策略解决:
当调用完va_start()操作后,ap已经指向了变参列表了;然后调用vprintf(const char *fmt, va_list ap)将参数进行输出。当然也可以调用vsprintf(char *str, const char *fmt, va_list ap)、vsnprintf(char *str, size_t size, const char *fmt, va_list ap)来将变参保存起来进行处理。
通过上面的描述,可以实现一个自己的printf了:
#include <stdarg.h>
#include <stdio.h>
int my_printf(cosnt char *fmt, ...)
{
va_list ap; //定义va_list 变量
va_start(ap, fmt); //让ap指向变参...
int n = vprintf(fmt, ap); //调用vprintf进行输出
return n; //返回输出的字符数,printf返回值是int
}
需要注意的地方:
- 在使用C语言的变参时,需要将变参(即...)放在最后一个参数的位置;并且变参前面至少要有一个普通的参数
- 顶
- 0
- 踩
- C语言变参使用
- C语言变参使用
- C语言变参使用
- C语言变参使用实例
- C语言 变参函数的使用
- C语言变参的使用
- C语言函数变参使用
- C语言 java 变参的使用
- C 语言 define 变参__VA_ARGS__使用
- c语言变参
- c语言变参函数-
- C语言变参技术
- C语言变参技术
- C语言变参,记录
- C语言的变参
- C语言变参处理
- c语言变参函数
- C语言变参函数
- 数字签名是什么?
- 大数据时代挑战就是商机
- ORA-00119: invalid specification for system parameter LOCAL_LISTENER ORA-00132: syntax error or unre
- C++ static关键字
- 变形空间和候选消除算法(Candidate-Elimination)C++实现
- C语言变参使用
- mysql的utf8mb4设置
- Shell脚本中参数传递方法常用有8种
- linux redis安装
- boost库学习及应用
- 树莓派使用360wifi2实现无线上网
- 最坏情况下,找到n个元素中第二小的元素需要(n-1)+(lgn向上取整+1)
- C语言:运行中获取宏名字的技巧
- 指针理解