當我們定義乙個函式時,有可能無法確定引數的個數,這是就需要用到變長引數函式,就想標準c函式printf一樣。一般這樣宣告:
void func(char* form, ...);
前面至少有乙個確定的引數。函式體內如何獲取這些引數呢?這就需要用到幾個巨集以及了解他們的原理。
函式引數是以資料結構——棧的形式訪問
,從右至左入棧。因此,從理論上說,我們只要探測到任意乙個變數的位址,並且知道其他變數的型別,通過指標移位運算,則總可以找到其他的變數。
中定義了幾個重要的巨集:
typedef char* va_list;
void va_start ( va_list ap, prev_param );/* ansi version */
type va_arg ( va_list ap, type );
void va_end ( va_list ap );
va_list
是乙個字元指標,可以理解為指向當前引數的乙個指標,取參必須通過這個指標進行。
在呼叫參數列之前,定義乙個
va_list
型別的變數,(假設
va_list
型別變數被定義為
ap);
然後應該對
ap 進行初始化,讓它指向可變參數列裡面的第乙個引數,這是通過
va_start
來實現的,第乙個引數是
ap 本身,第二個引數是在變參表前面緊挨著的乙個變數,即「
...」之前的那個引數;
然後是獲取引數,呼叫
va_arg
,它的第乙個引數是
ap,第二個引數是要獲取的引數的指定型別,然後返回這個指定型別的值,並且把
ap 的位置指向變參表的下乙個變數位置;
獲取所有的引數之後,我們有必要將這個
ap 指標關掉,以免發生危險,方法是呼叫
va_end
,他是輸入的引數
ap 置為
null
。通常va_start
和va_end
是成對出現。
例如:
int demo(char msg, ...)
va_end(argp);
}
C語言中變長引數例項
include include define sum arg.sum my name is arg char sum char a,變長引數的實現基於的是 c 語言預設的 cdecl 呼叫慣例中 自右向左壓棧的傳遞方式 比如 sum a,b,c 的各個引數在 棧中的相對順序為 top of stac...
C語言中不用巨集實現變長引數函式的原理及實現
一 前言 我們通常編寫的函式都是引數固定的,多了少了都會有錯,但是有時候我們是不能確定預先需要多少個引數的,而變長引數函式恰恰就能解決我們的問題。在unix中,提供了變長引數函式的編寫方法,主要是通過va list物件實現,定義在檔案 stdarg.h 中,變長引數函式的編寫有乙個固定的模板,模板很...
C語言變長引數實現
include include include 編寫可變長引數列表的函式案例 void minprintf char fmt,這個函式只處理格式字串和引數,格式的轉換則通過printf函式實現 省略號表示引數的數量和型別是可變的,省略號只能出現再參數列的尾部,minprintf不需要像printf ...