c语言之浅谈可变参数列表
一.什么是可变参数:通过将函数实现为可变参数形式,使得函数可以接受1个以上的任意多个不确定的参数。
可变参数的书写形式是(确定参数,...)
例如:下列子中int average(int n, ...)
其中int n 是要传入参数的个数,也是确定部分,...就是可变部分(即可变参数)
注意:
可变参数要被使用:
(1)知道每个参数传入的类型。
(2)并且需要知道一共传了多少个参数。
二.首先了解几个宏:
(1)va_list + 变量名(如arg):声明一个va_list类型(其实是char *)的变量arg。
(2)va_start(变量名,确定的参数变量):这是用来初始化的:如va_start(arg,n)
其含义是:将不可变参数前面的最后一个有名参数n的地址放入arg中(即arg指向n)。
(3)va_arg(变量名,类型):如va_arg(arg,int);
它的含义是:将arg所指解引用,然后强转成int型,并且arg指向下一个地址。
(4)va_end(变量名):如va_end(arg); 将arg释放。
三.可变参数的应用:
使用可变参数,实现函数,求函数参数的平均值。
#include <stdio.h>
#include <windows.h>
int average(int n, ...)
{
va_list arg;//定义一个指针变量arg来访问参数列表的不确定部分
va_start(arg, n);//将arg初始化使其指向最后一个确定部分
int i = 0;
int sum = 0;
for (; i < n; i++)
{
sum += va_arg(arg, int);//将arg 指向的位置解引用并且转换成int型,然后arg移到下一个不确定部分
}
va_end(arg);
return sum / n;
}
int main()
{
int a = 10;
int b = 20;
int c = 18;
int ret = average(3, a, b, c);
printf("%d\n", ret);
ret = average(2, a, b);
printf("%d\n", ret);
system("pause");
return 0;
}
下面有栈帧的结构理解一下可变参数如何实现的:
有上述例子可以知道访问不可变参数,通过可变的参数的前一个不可变参数即可得到。
四.可变参数的限制:
(1)可变参数必须要从头到尾逐个访问。a.可以半途终止。b.但是不能直接从中间访问。
(2)参数中至少要有一个命名参数。保证了可以使用va_start();进行初始化。
(3)这些宏无法直接判断参数的类型和个数。
(4)如果va_arg();指定了错误的类型,则后果不堪设想。