衆所周知,C語言的printf即實現了可變長度的參數,其實C語言標準庫就已經提供了一個接口供我們使用,經之我們可以很簡便的實現參數的可變長度參數。
通過查看C-API可以瞭解到這個
Macros:
va_start();
va_arg();
va_end();
Variables:
typedef va_list
其中va_start(),va_arg(),va_end()爲三個宏定義方法,va_list爲一個宏定義結構體,其具體實現均依賴於操作系統的實現,其聲明如下
void va_start(va_list list, last_arg);
type va_arg(va_list list, type);
void va_end(va_list list);
va_start將第一個參數list初始化爲...所代表的參數,從所給的last_arg參數處開始掃描(其實我覺得這個參數給得也沒多大意義,不管你給得是哪個參數,都只掃描...所代表的參數)
va_arg自動迭代各個參數,類似於Java中的Iterator
va_end關閉這個list
list爲自己定義的一個結構體
last_arg爲傳進來的參數中的最後一個
type爲你想讀取的參數的類型
下面以一個例子來進行演示
#include<stdarg.h> #include<stdio.h> //聲明一個參數,第二個int爲我所給出的last_arg void sum(char *, int,int, ...); int main(void) { sum("The sum of 15+13 is %d.\n", 11, 12, 15, 13); return 0; } void sum(char *string, int first_arg,int second_arg ...) { int sum = 0; va_list ap; int loop; /*注:這裏若不是省略號前的第二個參數,則會出現警告信息 *所以下面這兩行(我發現的)唯一的區別就是會不會出現警告*/ va_start(ap, second_arg); //va_start(ap, first_arg); /*注意下面這個2代表的是我有兩個參數,通過這個來遍歷*/ for (loop = 0; loop < 2; loop++) /*把list想像成一個棧,下面這個步驟就是彈出,也可以理解爲迭代*/ sum += va_arg(ap, int); printf(string, sum); va_end(ap); }
注意上面的程序中那個循環,或許你會說那個2是不就是建立在我已經獲悉有幾個參數了嗎。的確如此,不過可以解析後面的參數以獲取有幾個參數或者要求用戶輸入參數的個數(作爲last_arg),這裏我只是演示一下其運行機制罷了,更深一部的應用可以根據需要進行相應的擴展。