可变参数列表解析

本文介绍了C语言中的可变参数概念及其实现方法,包括如何使用stdarg.h头文件中的宏进行参数处理,以及va_list、va_start、va_arg和va_end等宏的作用。同时讨论了可变参数的限制。

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

什么是可变参数
就是通过将函数实现为可变参数的形式,可以使得函数可以接受1个以上的任意多个参数(不固定)。

  • 比如下段代码:
	int ret = average(3, 1, 2, 3);
	ret = average(4, 2, 3, 6, 9);
	
  • 这里想分别求两组数字个数不一样的平均值,那么这个函数的形参就需要用可变参数来实现;下面代码里面这个函数就可以实现这个问题
#include <stdarg.h>

int average(int n, ...)//      ...表示未知参数
{
	va_list arg;
	             //char * arg;
	int i = 0;
	int sum = 0;
	va_start(arg, n);
	                 //(arg=(char*)&n+4);
	for(i=0; i<n; i++)
	{	
		sum += va_arg(arg, int);
		               //sum += (*(int *)((arg +=4)-4))
	}
	va_end(arg);
	             //arg=(char *)0;
	return sum/n;
}
int main()
{
int ret = average(3, 1, 2, 3);
	printf("ret = %d\n", ret);//2
	ret = average(4, 2, 3, 6, 9);
	printf("ret = %d\n", ret);//5

	return 0;
}
  • 上面的va_list ,va_start ,va_arg ,va_end ; 这些我们平时不太见到的即为可变参数的语法。
  • 可变参数列表是通过宏来实现的,这些宏定义于 stdarg.h 头文件,它是标准库的一部分。这个头文件声明了一个类型 va_list 和三个宏——va_start ,va_arg va_end 。
  • 注意参数列表中的省略号:它提示此处可能传递数量和类型未确定的参数。
  • 点击几个语法转到函数定义,我们则可以看到它最直白的意思;上面代码块的注释即为它转化之后的代码;
  • VS源代码
    VS中源代码
    可变参数的实现过程是使用宏的封装。只要完成替换,我们就可以自行分析了
  • 声明一个 va_list 类型的变量 arg ,它用于访问参数列表的未确定部分。
  • 这个变量是调用 va_start 来初始化的。它的第一个参数是 va_list 的变量名,第2个参数是省略号前最后一个有名字的参数。初始化过程把 arg 变量设置为指向可变参数部分的第一个参数。
  • 为了访问参数,需要使用 va_arg ,这个宏接受两个参数: va_list 变量和参数列表中下一个参数的类型。在这个例子中所有的可变参数都是整型。 va_arg 返回这个参数的值,并使用 va_arg 指向下一个可变参数
  • 最后,当访问完毕最后一个可变参数之后,我们需要调用va_end。
  • 可变参数的限制
  • 注意:
  • 可变参数必须从头到尾逐个访问。如果你在访问了几个可变参数之后想半途终止, 这是可以的,但是,如果你想一开始就访问参数列表中间的参数,那是不行的。
  • 参数列表中少至有一个命名参数。如果连一个命名参数都没有,就无法va_start。
  • 这些宏是无法直接判断实际存在参数的数量。
  • 这些宏无法判断每个参数的是类型。
  • 如果在va_arg中指定了错误的类型,那么其后果是不可预测的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值