采用ANSI标准形式时, 参数个数可变的函数的 原型声明是:
type funcname(type para1, type para2, ...)
这种形式 至少需要一个普通的形式参数,后面的省略号不表示省略,而是函数原型的一部分。type是函数返回值和形式参数的类型。
不同的编译器,对这个可变长参数的实现不一样 ,gcc4.x中是采用内置函数的方法来实现。
接下来我们看看以下示例代码:
#include <stdarg.h>
#include <stdio.h>
int Sum (int n, ...)
{
int sum = 0, i = 0;
va_list p; // 定义一个变量 ,保存函数参数列表的指针。
va_start(p, n); // 用va_start宏初始化变量p,
// va_start宏的第2个参数n,
// 是一个固定的参数,
// 必须是我们自己定义的变长函数的最后一个入栈的参数,
// 也就是调用的时候参数列表里的第1个参数。
for (i = 1; i < n; ++ i) // i从1开始,遍历所有可变参数。
{
sum += va_arg(p, int); // va_arg取出当前的参数,
// 并认为取出的参数是一个整数(int) 。
}
return sum;
}
int main(void)
{
int num;
num = Sum(5, 1, 2, 3, 4);
printf("%d/n", num);
return 0;
}
当我们调用Sum函数时,传递给Sum函数的参数列表的第一个参数n的值是5,va_start 初始化p使其指向第一个未命名的参数(n是有名字的参数) ,也就是1(第一个),每次对 va_arg的调用,都将返回一个参数,并且把 p 指向下一个参数,va_arg 用一个类型名来决定返回的参数是何种类型,以及在 var_arg的内部实现中决定移动多大的距离才到达下一个参数。
==========================================================================
void AddText(HWND hWndLB, PCTSTR pszFormat, ...) {
va_list argList;
va_start(argList, pszFormat);
TCHAR sz[20 * 1024];
_vstprintf_s(sz, _countof(sz), pszFormat, argList);
cout<<sz;
va_end(argList);
}
AddText(NULL, TEXT("[%d] Nothing to process"), num);