您的位置:首页 > 其它

va_list及vsnprintf的用法

2017-09-06 22:32 232 查看

一、VA_LIST

VA_LIST 是在C语言中解决变参问题的一组宏,用于获取不确定个数的参数。

1、用法

(1). 首先在函数里定义一具VA_LIST型的变量,这个变量是指向参数的指针;

(2). 然后用VA_START宏初始化刚定义的VA_LIST变量;

(3). 然后用VA_ARG返回可变的参数,VA_ARG的第二个参数是你要返回的参数的类型(如果函数有多个可变参数,依次调用VA_ARG获取各个参数;

(4). 最后用VA_END宏结束可变参数的获取;

2、成员详解

(1). VA_START宏:获取可变参数列表的第一个参数的地址。va_start(ap,v)(ap是类型为va_list的指针且ap指向第一个变参的位置,即将第一个变参的地址赋予ap,v是可变参数最左边的参数);

(2). VA_ARG宏:获取可变参数的当前参数,返回指定类型并将指针指向下一参数。va_arg(ap,t)(t参数描述了当前参数的类型);

(3). VA_END宏:清空va_list可变参数列表。

3、通过栈进一步理解

C语言的函数形参是从右向左压入堆栈的,以保证栈顶是第一个参数,而且x86平台内存分配顺序是从高地址到低地址。因此似函数AVEInt(int var1,int var2,…,int varN)内存分配大致上是这样的:(可变参数在中间)

栈区:

|栈顶 低地址

|第一个参数var1 <– &v

|第二个参数var2 <– va_start(ap,v)后ap指向地址

|…

|函数的最后varN

|…

|函数的返回地址

|…

|栈底 高地址

va_list ap ; 定义一个va_list变量ap

va_start(ap,v) ;执行ap = (va_list)&v + _INTSIZEOF(v),ap指向参数v之后的那个参数的地址,即 ap指向第一个可变参数在堆栈的地址。

va_arg(ap,t) , ( (t )((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )取出当前ap指针所指的值,并使ap指向下一个参数。 ap+= sizeof(t类型),让ap指向下一个参数的地址。然后返回ap-sizeof(t类型)的t类型*指针,这正是第一个可变参数在堆栈里的地址。然后 用*取得这个地址的内容。

va_end(ap) ; 清空va_list ap。

注意:如果我们不需要一一详解每个参数,只需要将可变列表拷贝至某个缓冲,可用vsprintf函数;

二、vsnprintf

vsnprintf将可变参数格式化输出到一个字符数组

1、函数简介

(1)、函数原型:int vsnprintf(char *str, size_t size, const char *format, va_list ap);

参数:

(2)、str输出到的数组,size指定大小,防止越界,format格式化参数,ap可变参数列表函数用法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: