可變引數 函式 可變引數列表 1

2021-05-28 05:39:53 字數 1186 閱讀 3377

我們在c語言程式設計中有時會遇到一些引數個數可變的函式,即函式的入參個數和型別是不確定的,例如printf()函式,其函式原型為:

int printf(char* format, ...);

它除了有乙個引數format固定以外,後面跟的引數的個數和型別是可變的(用三個點「…」做引數佔位符),實際呼叫時可以有以下的形式:

printf("%d",i);

printf("the number is %d ,string is:%s", i, s);    

以上這些東西已為大家所熟悉。但是究竟如何寫可變引數的c函式以及這些可變引數的函式編譯器是如何實現的呢?

為了說明問題,通過編寫乙個自定義的可處理可變長度引數的函式minprintf來說明。

printf函式的定義格式為:

int printf(char *fmt, …)

這裡,…的含義為引數的型別和個數是不確定的。…宣告只能出現在引數列表的尾部。函式返回輸出的字元個數。

我們自己定義的函式minprintf宣告格式為:

void minprintf(char *fmt, …)

因為這裡我們不需要返回輸出的字元個數,所以定義返回型別為void。

帶有可變長度引數的函式裡,即沒有引數的型別也沒有引數的個數,那麼編譯器是怎麼處理這樣的函式的呢?

標準標頭檔案stdarg.h定義了一系列的巨集來處理這個可變長度的引數列表。這個標頭檔案的實現會因編譯器的不同而各異,但它們的介面卻是相同的。

型別va_list:定義為這樣乙個資料型別,迴圈使用且每次指向乙個可變的引數;在我們舉的例子minprintf函式裡指變數ap(argument pointer);

函式va_start:初始化ap,使ap指向第乙個可變的引數;注意,這個函式必須在使用ap前被呼叫;minprintf必須至少有乙個確定的引數,而且,最後乙個確定的引數才是va_sart函式的乙個入參;

函式va_arg:返回乙個可變長度引數的值並使ap指向下乙個可變長度引數,該函式使用乙個型別名來確定要返回的型別和指標ap需要移動的位元組單位;

函式va_end:做一些必要的清理工作,需要在程式結束前呼叫。

other:

int vprintf(const char *format, va_list arg)

函式vprintf與printf等價,只是用arg替換了變數引數列表,arg由va_start巨集初始化,並且va_arg可能會呼叫它。

可變引數列表

模擬實現printf函式 va list是在c語言中解決變參問題的一組巨集,所在標頭檔案 include 用於獲取不確定個數的引數 va start,函式名稱,讀取可變引數的過程其實就是在堆疊中,使用指標,遍歷堆疊段中的引數列表,從低位址到高位址乙個乙個地把引數內容讀出來的過程 va arg,這個巨...

可變引數列表

小二,上 class a public class varargs two param static void twostringparam string a,string b three param 參照上兩種寫法,一直往後面加。是不是感覺很憂傷 幸好這不是真的。string.a static v...

可變引數列表

測試環境 vs2008 1 可變引數列表 為什麼需要可變引數呢?在函式原型中,列出了函式期望接受的引數,原型只能顯示固定數目的引數,如果函式原型列出的引數與可呼叫引數不匹配或數目不一樣,程式將無法執行。例如,我們想要求一系列值的平均值,這裡的一系列的數目是不確定的,如果這些值儲存於陣列中,這個任務就...