stdarg.h头文件定义了一个变量类型va_list和三个宏,这三个宏可用于在参数个数未知(即参数个数可变)时获取函数中的参数。
可变参数的函数通常在参数列表的末尾使用省略号(,...)定义的。
库变量
库宏
C库宏void a_start(va_list ap, list_arg)初始化ap变量,它与va_arg和va_end宏一起使用。last_arg是最后一个传递给函数的已知的固定参数,即省略号之前的参数。
这个宏必须在使用va_arg和va_end之前被调用。
声明
void va_start(va_list ap, last_arg);
参数
·ap -- 这是一个va_list类型的对象,它用来存储通过va_arg获取额外参数所必须的信息。
·last_arg -- 最后一个传递给函数的已知的固定参数。
实例
#include<stdarg.h>
#include<stdio.h>
int sum(int, ...);
int main(void)
{
printf("10、20 和 30 的和 = %d\n", sum(3, 10, 20, 30) );
printf("4、20、25 和 30 的和 = %d\n", sum(4, 4, 20, 25, 30) );
return 0;
}
int sum(int num_args, ...)
{
int val = 0;
va_list ap;
int i;
va_start(ap, num_args);
for(i = 0; i < num_args; i++)
{
val += va_arg(ap, int);
}
va_end(ap);
return val;
}
编译运行结果如下:
10、20 和 30 的和 = 60
4、20、25 和 30 的和 = 79
C库宏type va_arg(va_list ap, type)检索函数参数列表中类型为type的下一个参数。它无法判断检索到的参数是否是传给函数的最后一个参数。
声明
type va_arg(va_list ap, type)
参数
·ap -- 这是一个va_list类型的对象,存储了有关额外参数和检索状态的信息。该对象应在第一次调用va_arg之前通过调用va_start进行初始化。
·type -- 这是一个类型名称。该类型名称是作为扩展自该宏的表达式的类型来使用的。
返回值
该宏返回下一个额外的参数,是一个类型为type的表达式。
实例
#include <stdarg.h>
#include <stdio.h>
int sum(int, ...);
int main()
{
printf("15 和 56 的和 = %d\n", sum(2, 15, 56) );
return 0;
}
int sum(int num_args, ...)
{
int val = 0;
va_list ap;
int i;
va_start(ap, num_args);
for(i = 0; i < num_args; i++)
{
val += va_arg(ap, int);
}
va_end(ap);
return val;
}
编译运行结果:
15 和 56 的和 = 71
C库宏void va_end(va_list ap)允许使用了va_start宏的带有可变参数的函数返回。如果在从函数返回之前没有调用va_end,则结果未定义。
声明
void va_end(va_list ap)
参数
·ap -- 这是之前由同一函数中的va_start初始化的va_list对象。
实例
#include <stdarg.h>
#include <stdio.h>
int mul(int, ...);
int main()
{
printf("15 * 12 = %d\n", mul(2, 15, 12) );
return 0;
}
int mul(int num_args, ...)
{
int val = 1;
va_list ap;
int i;
va_start(ap, num_args);
for(i = 0; i < num_args; i++)
{
val *= va_arg(ap, int);
}
va_end(ap);
return val;
}
编译并运行结果:
15 * 12 = 180
参考:
https://www.yuque.com/docs/share/d48aa2e2-5c41-4601-9b1c-592e6c9e9fd3