VA_LIST 是在C语言中解决变参问题的一组宏,所在头文件#include <stdarg.h>
,用于获取不确定个数的参数。首先,我们来看看C语言中是如何定义。先看其中比较简单的一种定义,分析完一种,其他实现也可触类旁通。
va_list,定义为字符串指针:
typedef char * va_list;
VA_START宏,获取可变参数列表的第一个参数的地址(ap是类型为va_list的指针,v是可变参数最左边的参数):
#define va_start(ap,v) ( ap = (va_list)&v + 4 )
因为第一个参数是固定的,第一个参数的地址加上4(一个地址的长度),就等于第二个参数的地址。如果要深究,就要研究C语言参数入栈相关知识,参数压栈的方向是从右往左,这里简单提下。
VA_ARG宏,获取可变参数的当前参数,返回指定类型并将指针指向下一参数,实际应用中经常用格式化函数vsprintf代替VA_ARG宏。
VA_END宏,清空va_list可变参数列表:
#define va_end(ap) ( ap = (va_list)0 )
下面展示一个简单的程序流程
char buffer[80] = {
0};
int cnt;
va_list argptr; //初始化va_list变量argptr
va_start(argptr, fmt); //获取可变参数列表的第一个参数的地址argptr
cnt = vsprintf(buffer, fmt, argptr);//格式化输出数组buffer
va_end(argptr);//清空va_list可变参数列表
有了上面基础知识,再来看看printf的一种实现