C C 可變引數

2021-07-15 20:19:28 字數 1182 閱讀 1244

為了解決這些問題,我們首先要解釋cdecl呼叫約定(參見論調用約定),所有使用不定引數的函式必須是使用cdecl(全域性函式)或者this call(類成員函式)呼叫約定。該約定對於引數傳遞規定如下:

引數從右向左入棧(也就是如果你呼叫f(a,b,c),則c先入棧,然後是b,最後是a入棧)

呼叫者負責清理堆疊

在設計具有不定引數列表的函式的時候,我們有兩種方法來確定到底多少引數會被傳遞進來。

方法1是在型別固定的引數中指明後面有多少個引數以及他們的型別。printf就是採用的這種方法,它的format引數指明後面每個引數的型別。

方法2是指定乙個結束引數。這種情況一般是不定引數擁有同樣的型別,我們可以指定乙個特定的值來表示引數列表結束。

#include "stdarg.h"

using

namespace

std;  

intsum(

intcount, ...)  

va_end(args);  

return

sum_value;  

}  int

_tmain(

intargc, _tchar* argv)  

在vc6,va_start函式定義為:

_intsizeof(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

#define

va_start(ap,v)  ( ap = (va_list)&v + _intsizeof(v) )

其中_intsizeof(n)計算比n大的sizeof(int)的最小倍數,如果n=101,則_intsizeof(n)為104。

va_start執行完畢後,ap指向變數v後第乙個4位元組對齊的位址。例如,v的位址為0x123456, v的大小為13,則v後面的下乙個與字邊界對齊的位址為0x123456+0x0d=0x123463再調整為與4位元組對齊的下乙個位址,也就是 0x123464.

va_arg函式定義為:

va_arg(ap,t)    ( *(t *)((ap += _intsizeof(t)) - _intsizeof(t)) )

分析與va_start一樣,它的結果是使ap指向當前變數的下乙個變數。

這樣,我們只要在開始時使用va_start把不定引數列表賦值給ap,然後依次用va_arg獲得不同引數即可。

C C 可變引數

函式 使用va list巨集組解決變參問題 1 首先定義va list型的變數,這個變數是指向引數的指標。2 然後用va start巨集初始化剛定義的va list變數,這個巨集的第二個引數是 第乙個可變引數的前乙個引數 3 再用va arg得到可變引數,第二個引數是 可變引數 的型別。4 最後用v...

C C 可變引數

函式 使用va list巨集組解決變參問題 1 首先定義va list型的變數,這個變數是指向引數的指標。2 然後用va start巨集初始化剛定義的va list變數,這個巨集的第二個引數是 第乙個可變引數的前乙個引數 3 再用va arg得到可變引數,第二個引數是 可變引數 的型別。4 最後用v...

c c 可變引數

c語言支援在函式定義時,用 省略號代表可變引數列表,中最常見的可變引數的例子是printf引數,c 的可變引數繼承自c。可變引數的引數列表在壓棧時,同一組引數是按照從右向左的順序,逐個由高位址向低位址壓倒棧中。知道到最左邊乙個引數的位址 型別和右邊每個引數的型別,就可以計算出每乙個引數的位址,這是可...