#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>
int Max(int n, ...)
{
va_list arg;
int i = 0;
int max = 0;
int t = 0;
va_start(arg, n);
max = va_arg(arg, int);
for (; i < n - 1; i++)
{
max = (max>(t = va_arg(arg, int)) ? max : t);
}
va_end(arg);
return max;
}
int main()
{
int max = 0;
int n, a, b, c, d;
n = 4;
a = 3;
b = 9;
c = -1;
d = 11;
max = Max(n, a, b, c, d);
printf("%d \n", max);
system("pause");
return 0;
}
在进行可变函数列表的传参的时候,要引头文件stdarg.h。
然后传参的时候至少要传一个参数进去,这个参数一般可能会传参数个数,当然也可能是别的东西。
在函数调用的时候,在栈上会开辟一块内存空间,形成栈帧结构。此时,形参创建完毕,在栈上的存放方式为连续存放,那么我们传一个参数过去,通过这个参数,可以轻易的访问到别的参数。这就是可变参数列表的核心思想。
然后我们来仔细分析一下这段代码,va_list(参数列表)其实是用typedef重新定义的一个类型,它的原型其实就是char*,正因为创建了这个指针才可以轻松的访问到其他参数。因为这段代码的目标是求几个数中是最大值,所以我传进去的唯一一个可见参数其实就是后面的参数个数,而又因为寻求最大值是要进行两两比较,所以循环次数设定为n-1次。
va_start是用来初始化指针的,我们传了两个参数进去,第一个arg是为了让指针指向参数的地址,后面的类型是为了保证下一个参数能够正确的被访问。因为指针+1,加的是类型的大小。
接下来的va_arg就是用来访问每一个参数的,每调用一次va_arg,就会访问下一个参数。当程序运行完之后,调用va_end,它的左右是让指针指向NULL,不然可能会出现意想不到的错误。
参考文章: