C語言中變長引數的函式的實現

2021-07-11 09:59:38 字數 1143 閱讀 2960

當我們定義乙個函式時,有可能無法確定引數的個數,這是就需要用到變長引數函式,就想標準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 ...