在某些应用中,我们希望一个参数的参数个数是可变的,来满足需求,如stdio.h中的库函数printf和scanf。如下例子:
#include <iostream>
#include <stdarg.h>
using namespace std;
int max1(int num,int s...)
{
va_list ap;
int m = s;
va_start(ap, s);
for(int i = 1; i < num; i++)
{
int t = va_arg(ap, int);
if(t > m)
m = t;
}
return m;
}
int main(int argc, const char * argv[]) {
// insert code here...
std::cout << "Hello, World!\n";
cout << "请输入5个数: ";
int a,b,c,d,e;
cin >> a >> b >> c >> d >> e;
cout << a << b << c << d << e << endl;
cout << "a和b中较大者为: " << max1(2,a,b) << endl;
cout << "5个数中较大者为: " << max1(5,a,b,c,d,e) << endl;
return 0;
}
结果为:
max1函数就是一个可变参数函数,其参数表中的省略号表示其后还可能带有一些参数,在编写一个可变参数函数时,通常借助文件系统stdarg.h中的va_list和三个宏va_start(),va_arg()以及va_end()。下面单独分析下这些参数。
1、va_list:实际上是void指针类型,其说明为:typedef void * va_list;
2、va_start():实际是一个宏,void va_start(va_list argPtr,last _param);其中第一个参数是va_list类型的指针,第二个参数为可变参数形参表中最后一个固定参数的名字,该宏的作用是讲argPtr指针指向的可变参数之形参表中得最后一个固定参数的尾部,也就是将argPtr指针指向可变参数函数之形参表中的第一个可变参数,为读取第一个可变参数作准备。
3、va_arg():宏定义,type va_arg(va_list argPtr, type):第二个参数是可变形参的数据类型,如果是C++的类,还可以是父类类型,该宏的作用是从argPtr指针指向的内存地址读取一个type类型的数据,同时使argPtr指针指向下一个可变参数。
4、va_end():宏,void va_end(va_list argPtr):该宏只有一个va_list参数,作用是结束可变参数的存取,使可变参数能正常返回。