在讲可变参数之前,我们需要了解一下参数入栈的方式。一般来说参数入栈的方式是自右向左,但也有特殊情况,不过大家记住自左向右就可以解决大多问题了。下面通过图片来分解参数是如何自左向右入栈的:
经过画图分析,大概就可以深刻理解了吧,下面我来分享一个题,请读者思考:
int main()
{
int arr[] = {1,2,3,4,5};
int i = 1;
printf("%d,%d\n",arr[i],arr[i++]);//答案是?
return 0;
}
大家一定要结合参数入栈的方式好好思考哦。
大家还记得求两个数的平均值的函数怎么写吗?三个数的平均值?四个数的平均值?n个数的平均值?
int Avg1(int a,int b)//两个数的平均值
{
return a+b/2;
}
int Avg2(int a,int b,int c)//三个数的平均值
{
return a+b+c/3;
}
int Avg3(int n,int a,int b,int c,int d,int e)//求1~5个数的平均值
{
int sum = 0;
assert(n != 0);
if(n == 1)
sum = a;
else if(n == 2)
sum = a+b;
else if(n == 3)
sum = a+b+c;
else if(n == 4)
sum = a+b+c+d;
else if(n == 5)
sum = a+b+c+d+e;
else
sum = -1;
return sum/n;
}
在主函数中调用函数Avg3解决两个数的平均值时,我们需要这样写:Avg3(2,10,20,0,0,0);那我们可以看到参数列表中会有3个0,这样既不好看,又容易出错,我们有没有办法求几个数的平均值就写几个参数呢,这就要用到我们今天的可变参数了:
int Avg(int n,int ...)
{
va_list list;//游标(一个封装的指针)
int sum = 0;
va_start(list,n);//定位,找到"..."的开头
for(int i=0;i<n;i++)
{
sum += va_arg(list,int);//取出"..."中的整形数据
}
va_end(list);
}
这就是一个可变参数的例子,在这个程序里边,n有两个作用,一是帮助找到“...”,二是记录“...”中省略的数据的个数。
最后揭秘一下思考题的答案:3,2