可变参数:stdarg.h

作者:追风剑情 发布于:2020-3-23 17:27 分类:C

stdarg.h头文件提供一种方法定义参数数量可变的函数。这种函数的原型有一个形参列表,列表中至少有一个形参后面跟有省略号:

void f1(int n, ...) //有效
int f2(int n, float x, int k, ...) //有效
double f3(...) //无效

在下面的表中,parmN是省略号前面的最后一个形参的标识符。在上面的例子中,第1种情况的parmN为n,第2种情况的parmN为k。

头文件中声明了va_lis类型表示储存形参列表中省略号部分的形参数据对象。下面列出了3个带可变参数列表的函数中用到的宏。在使用这些宏之前要声明一个va_list类型的对象。

可变参数列表宏
描述
void va_start(va_list ap, parmN) 该宏在va_arg()和va_end()使用ap之前初始化ap,parmN是形参列表中最后一个形参名的标识符
void va_copy(va_list dest, va_list src) 该宏把dest初始化为src当前状态的备份(C99)
type va_arg(va_list ap, type) 该宏展开为一个表达式,其值和类型都与ap表示的形参列表的下一项相同,type是该项的类型。每次调用该宏都前进到ap中的下一项
void va_end(va_list ap) 该宏关闭以上过程,可能导致ap在再次调用va_start()之前不可用
void va_copy(va_list dest, va_list src) 该宏把dest初始化为src当前状态的备份(C99)

变参函数比使用变参宏更复杂,但是函数的应用范围更广。

示例:


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

double sum(int, ...);

int main(int argc, char* argv[])
{
	double s, t;

	s = sum(3, 1.1, 2.5, 13.3);
	t = sum(6, 1.1, 2.1, 13.1, 4.1, 5.1, 6.1);
	printf("return value for "
		"sum(3, 1.1, 2.5, 13.3):		%g\n", s);
	printf("return value for "
		"sum(6, 1.1, 2.1, 13.1, 4.1, 5.1, 6.1): %g\n", t);

	system("pause");
	return 0;
}

double sum(int lim, ...)
{
	va_list ap; // 声明一个对象储存参数
	//va_list apcopy;
	double tot = 0;
	int i;

	va_start(ap, lim); // 把ap初始化为参数列表
	//va_arg()不提供退回之前参数的方法,所以有必要保存va_list类型变量的副本
	//va_copy(apcopy, ap);
	for (i = 0; i < lim; i++)
	{
		tot += va_arg(ap, double); // 访问参数列表中的每一项
	}
	va_end(ap); // 清理工作
	//调用了va_end(ap)后,只有用va_start(ap, lim)重新初始化ap后,才能使用变量ap

	return tot;
}


运行测试

111.png

标签: C语言

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号