printf("This is an integer: %d, That is a float: %s", 1, 2.0);
在上面的例子裏,printf()接收三個參數,第一個是要打印的字串,裏面有兩個參數: git
* %d github
* %s 編程
後面是這兩個參數對應的實際值: bash
* 1 函數
* 2.0 spa
在上面的例子裏,printf()接收了三個參數。再看下面這個例子:.net
printf("Hello, world!");printf()此次只接收了一個參數。換言之,printf()接收的參數個數是*可變的*。這是如何實現的呢?在C語言裏面,咱們能夠在函數定義時使用 "..." 來定義可變長度參數,好比:
a_function(int i, ...);
先將固定參數寫在最前面,後面再用"..."來聲明這個函數接收可變長數參數。 而後,咱們在函數內部使用stdarg.h裏面定義的一個struct和幾個宏來實現對可變長度參數的讀取: 翻譯
* va_list code
* va_start() xml
* va_arg()
* va_end()
這個幾東西的使用方法很是簡單,在stdarg.h的manpage裏面說明的很詳細。查看stdarg.h的manpage可用下面的命令:
man 3 stdarg裏面有這樣一段說明:
簡單翻譯一下,就是首先調用va_start(),而後初始化ap,以後使用va_arg()來處理可變長度參數。最後,使用va_end()來清理ap。 我製做了一個實際的例子,放在了github上面:The va_start() macro must be called first, and it initializes ap, which can be passed to va_arg() for each argument to be processed. Calling va_end() signals that there are no further arguments, and causes ap to be invalidated. Note that each call to va_start() must be matched by a call to va_end(), from within the same function.
https://github.com/liweinan/learnc/blob/master/stdarg.c關於這個代碼,有些要說明的地方: * 這裏面有兩個可變長度參度的函數:一個是求平均數的average(),另外一個是模擬printf的min_printf() * average()這個函數想說明的是:第一個固定參數在實際應用時是必不可少的,須要它的配合來使用後面的參數。 * min_printf()這個函數想說明的是: 如何使用第一個固定參數裏面的值配合讀取後面可變長度參數的數據類型。 代碼裏面的說明已經很詳細,能夠仔細看下。下面是這個例子的使用方法: 首先從git遷出代碼:
git clone git://github.com/liweinan/learnc.git而後編譯例子:
make stdarg.o最後運行例子,下面是命令和輸出結果:
% make play_stdarg ./stdarg.o average: 2.300000 The ultimate answer of life is: 42全文目錄 http://bluedash.net/spaces/Linux編程每週一講-目錄