va_list介绍

一、在介绍va_list之前,首先介绍众所周知的printf()函数的实现,请看下面的代码:

int printf(char const* __restrict fmt,...)
{
	va_list arg_ptr;
	
	va_start(arg_ptr,fmt);
	
	int ret = vfprintf(stdout,fmt,arg_ptr);

	va_end(arg_ptr);

	return ret;
}


printf函数的形参列表长度是可变的,这种函数被称为变参函数,即参数的个数不确定。相比C++中的重载中对参数的个数的限制,变参函数使用起来比较灵活。

下面看下该函数是如何显现的。其主要使用的va_list类型才使得printf函数具有如此的灵活性。所以printf的使用灵活性应归功于va_list。


二、可变参函数的声明

在无法给出所有传递给函数的参数的类型和数目时,可以使用省略号(...)指定函数参数表。有如下几种形式:

	1 void fun1(int a, double b, ...); //给出确定的几个参数,其他用省略号
	2 void fun2(int a ...);            //省略号前有或者没有逗号都是可以的
	3 void fun3(...);                  //也可以不确定任何参数,但和没有参数是不一样的


三、va_start,va_arg,va_end三个宏的介绍:

下面三个宏是来调用操作可变参数:

	#include <stdarg.h>

	void va_start(
 	 	 va_list arg_ptr, //指向参数列表的指针
   				prev_param 	   //最后一个显式声明的参数,以用来获取第一个可变参数的位置
	);

	type va_arg( 	 
	 	va_list arg_ptr,  	
	 			type  //要获取的参数类型,如char,int,float等
	);		

	void va_end(
 	 	 va_list arg_ptr 
	);


四、va_start,va_arg,va_end三个宏的使用:

1、定义一个va_list变量,该变量是指向可变参数的指针。

2、使用va_start初始化刚刚声明的va_list变量。第二个参数是可变参数最后一个显式声明的参数。

3、使用va_arg返回可变参数的值,第二个参数是该可变参数的类型。注意需要确定va_list变量是否是指向你想要的变量。

4、使用va_end清空第一步声明的va_list变量为NULL.


注意:1、可变参数的类型和数目不能通过这三个宏来获取,只能通过程序来控制。

    2、编译器对可变参函数的原型检测不是很严格,可能会影响代码质量。


五、具体使用详见第一部分的printf函数的实现。


六、关于va_list和这三个宏是如何定义,请自行查看MFC中头文件stdio.h,stdarg.h。当然不用的编译器,有不同的定义。



引用:  va_end() 对由 va_start() 或者 va_copy() 初始化的 va_list 类型对象的执行清理过程。va_end() 会修改 va_list 对象实例,使其不再可用。 如果没有相对应的对 va_start() 或者 va_copy() 函数的调用,或者如果在一个函数调用 va_start() 或者 va_copy() 函数之前没有调用 va_end() ,行为没有定义,即在这些情况下,没有定义如何去处理。 引用: va_list 是一个类型,用于表示可变参数列表。va_start() 是一个函数,用于初始化 va_list 类型的对象。va_copy() 也是一个函数,用于将已有的 va_list 类型对象内容拷贝到另一个 va_list 类型对象。va_arg() 是一个函数,用于获取 va_list 对象指针指向位置的下一个参数的值。 根据引用和引用的内容,va_list 是用于表示可变参数列表的类型,而 va_start() 是用于初始化 va_list 对象的函数。通过调用 va_start() 函数,我们可以将一个 va_list 对象和可变参数列表的第一个参数进行关联。这个对象可以被之后的操作所使用。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C/C++可变参数列表参数处理方法va_listva_start()、va_copy()、va_arg()、va_end()](https://blog.csdn.net/StoryZX/article/details/125748675)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值