可变参数即表示参数个数可以变化,可多可少,也表示参数的类型也可以变化,可以是int,double还可以是char*,类,结构体等等。
#include <stdio.h>
#include <stdarg.h>
int average(int n,...)
{
int ret = 0;
int sum = 0;
int i = 0;
va_list arg; //初始化arg为char类型指针
va_start(arg,n); //将arg指向n的右边第一位参数
for(i=0; i<n; i++)
{
sum += va_arg(arg,int); //取当前参数的值并将arg指向下一个参数
}
va_end(arg); //将arg清空为NULL
ret = sum/n;
return ret;
}
int main()
{
int aver = average(4,3,2,1,2);
printf("%d\n",aver);
return 0;
}
一一简介一下
va_list:按下F12看下va_list定义
由此可见va_list相当于 char* ,使用它就相当于定义一个char 指针。
va_start(arg,n) :看定义
va_start 是一个宏,编译时被_crt_va_start替换,再看看_crt_va_start
其中的_ADDRESSOF作用就相当于取地址操作&,_INTSIZEOF相当于提升到一个int的大小,如果n是1~4那么结果就是4;5~8就是8;9~12就是12,以此类推;
由此可见va_start的左右就是将n右边的第一个参数地址给arg(形参在栈中是先压最右边的参数,由于栈空间是从高地址向低地址写入,所以最上面的也就是n)
va_arg(arg,int):看定义()
简化一下就等价于(*(int*)(arg += 4)-4);
arg先+4,此时arg指向下一个参数地址,再-4则返回的是当前参数的内容。非常漂亮的代码。
va_end(arg):定义
arg = (char*)0;
arg = NULL;
va_end(arg)的作用就是将arg指针置为NULL.