va_list及vsnprintf的用法

本文介绍了C语言中处理变参数的宏va_list及其使用方法,包括VA_START、VA_ARG和VA_END的详细解释,以及通过栈理解va_list的工作原理。此外,还讲解了vsnprintf函数,它是将可变参数格式化输出到字符数组的函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、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可变参数列表函数用法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值