採用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);