在使用可变长参数时发现的一个问题,首先先放一段代码和它的运行结果:
void Print(int m, int n, ...)
{
va_list args;
va_start(args, m);
for (int i = 0; i < 4; i++)
{
int arg = va_arg(args, int);
cout << arg << " ";
}
cout << endl;
va_end(args);
va_start(args, n);
for (int i = 0; i < 4; i++)
{
int arg = va_arg(args, int);
cout << arg << " ";
}
cout << endl;
va_end(args);
}
int main()
{
Print(4, 4, 1, 2, 3, 4);
system("pause");
return 0;
}
产生这样结果的原因就在于va_start的第二个参数不同:原先一直以为va_start的第二个参数是参数的个数,查了一些资料,找到va_start的定义后发现,va_start的第二个参数是可变长参数最左边的地址。
va_start的定义如下:#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
#define va_start _crt_va_start
#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
由此可以看出ap,也就是第一个参数是一个va_list类型的变量,它是一个指针,指向v后面一个变量的地址。
现在就可解释之前代码产生的结果了,第一个va_start第二个参数是m,因此args指向的是n,输出的依次是4,1,2,3
4是n的值,1,2,3是传入的可变参数;第二个va_start的第二个参数是n,args指向的是n后的参数,也就是传入的可变长参数的一个值,所以输出的就是1,2,3,4.
最后要注意的是千万不要把va_start的第二个参数看成参数的个数,从而传入一个常量,程序一般会直接崩溃。