1) 典型例子
printf(“ %d, %d, %d”, a, b,c )
int Func( int a, …) ; //C++用法
int Func(); //C用法
2) 用法
l include <stdarg.h>
l va_start(va_list, 前一个参数变量)
#define char* va_list
#define _ADDRESSOF(v) ( &reinterpret_cast<const char &>(v) )
取得变量在堆栈中的地址
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
以上使得大小是4的倍数
#define va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
l va_arg(va_list, 要取的参数类型)
#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
l va_end(va_list)
#define _crt_va_end(ap) ( ap = (va_list)0 )
注意:1)至少需要指定第一个参数,因为va_start需要它定位
堆栈中参数的地址;
2) 一般来说,可以考虑利用多态来替代可变参数。
3) 具体使用
int customarg( int a, ...)
{
va_list arg_ptr;
va_start(arg_ptr, a);
int b = va_arg(arg_ptr, int);
int c = va_arg(arg_ptr, int);
long d = va_arg(arg_ptr, long);
char* p = va_arg(arg_ptr, char*);
double e = va_arg(arg_ptr,double);
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
cout<<"d = "<<d<<endl;
cout<<"p = "<<p<<endl;
cout<<"e = "<<e<<endl;
va_end(arg_ptr);
return a;
}
customarg1(2,33,4444444);
customarg(2,33,4444444,777777777,"hello",443.3);
可见:
1)用可变参数时,需要有一个地方指出参数的个数,一般就
用第一个参数。
2)在堆栈中每个变量其实是按4个字节对齐的(入栈出栈是按
字的),否则定位的时候就会出错,从_INTSIZEOF宏的定
义可以看出。
4) 类似printf的使用
不用自己解析可变参数:
l void Function( const string format, ... )
{
va_list args;
static const int nBUFFERSIZE = 1024;
char szTempBuffer[ nBUFFERSIZE ];
va_start( args, format);
StringCchVPrintf( szTempBuffer, nBUFFERSIZE, format.c_str(), args );
cout<<szTempBuffer<<endl;
}
l Function(“Hello %s, your age is %d/n”, “Ming”, 29);