想想我们常使用的c函数printf();
printf("sum of %d, %d, %d, %d: %d\n", 1, 3, 5, 7, sum(1, 3, 5, 7));
of course, the result is: sum of 1, 3, 5, 7: 16;
为什么printf()可以使用个数不定的变量?这是因为它内部使用了va_*系列函数(准确地说是宏)。
我们看看printf()的定义:
printf(const char *fmt, ...);
我们看到printf()函数的参数列表主要包含两个重要的元素:
1.const char *fmt,这是唯一一个已知的变量。
2. ...,代表2nd,3rd,...等未知变量。
注:未知变量必须位于变量列表的末位。
那么如何表达这些未知变量呢?
va_list类型(注意,这是一个类型)包含了此类变量列表的信息。So, 如果我们想要获取未知变量的信息,我们这必须定义一个变量:
va_list ap;
void va_start(va_list ap, paraN);
Initializes ap to retrieve the additional arguments after parameter
//初始化ap,并使ap接收paraN之后的变量。也就量说paraN是最后一个已知变量
// va_start与va_end是一对宏,调用了va_start以示开始,就必须调用va_end以示结束。
<pre name="code" class="cpp">void PrintFloats (int n, ...)
{
int i;
double val;
printf ("Printing floats:");
// 定义一个接收variable arguments的变量。</span>
va_list vl;
// 初始化vl,以使vl指向n后的第一个variable argument.</span>
va_start(vl,n);
for (i=0;i<n;i++)
{
// 从vl中提取variable arguments。</span>
// 必须知道数据类型,如此例中的double。</span>
// 每次va_arg的调用都会改变vl的状态。这样下一次的调用就会返回下一个variable argument。</span>
val=va_arg(vl,double);
printf (" [%.2f]",val);
}
// 取数完成.调用va_end()释放vl。</span>
va_end(vl);
printf ("\n");
}