C/C++函數變長參數列表實現

在C編譯器通常提供了一系列處理可變參數的,實現就像printf()那樣的變長參數列表,這樣可以屏蔽不同的硬件平臺造成的差異,增加程序的可移植性。這些宏包括va_startva_argva_end等,這些宏都是在頭文件<stdarg.h>裏定義的。
採用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);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章