c語言中有很多變參的使用,例如printf()的原型是int printf(const char *fmt, ...),那麼c語言是如何解析和處理這些變參的呢?下面進行簡單的總結:
c語言中定義了下面的一些巨集,專門用來處理變參:
va_start(va_list ap, char *fmt)
va_arg(va_list ap , type) //type是指引數的型別(比如int、char*、double)
va_end(va_list ap)
從上面三個巨集可以看到,它們都有乙個va_list型別的引數,那麼va_list是什麼呢?如何定義的呢?
typedef char* va_list;可以看到va_list其實就是char*
下面繼續解析上面的三個巨集:
其中ap是va_list型別的,即可變引數列表;而fmt就是printf等類似函式的引數,指明引數的型別等,例如常見的有:%d%s%c%f等等
va_list()操作進行後的效果是:使得ap指向fmt後面的引數列表,即"...".c語言函式引數是從右向左壓棧的
這個操作要在其他兩個操作前面執行
在執行完va_start()操作後,ap就指向了變參的列表,這個時候就可以對變參列表進行操作了,是通過對ap進行操作實現的,因為此時ap指向變參列表
va_arg(va_list ap, type)的結果是這樣的:執行完這個操作後,首先返回ap當前指向的引數;然後ap向後移動,執行下乙個引數;因此va_arg()是要迴圈呼叫的,直到所有引數都獲得
type是當前引數的型別
當上面操作進行完後,ap不再使用了,需要呼叫va_end()操作將ap給清空
根據上面的描述,在c語言中處理變參的過程大概是這樣的:
從上面的過程可以看到,在執行第三步的時候有點麻煩,比如事先根本不知道引數的型別等,這樣呼叫va_arg()就不太方便了;而在實際中這樣的現象是很多的,可以採用下面的策略解決:
當呼叫完va_start()操作後,ap已經指向了變參列表了;然後呼叫vprintf(const char *fmt, va_list ap)將引數進行輸出。當然也可以呼叫vsprintf(char *str, const char *fmt, va_list ap)、vsnprintf(char *str, size_t size, const char *fmt, va_list ap)來將變參儲存起來進行處理。
通過上面的描述,可以實現乙個自己的printf了:
#include
#include
int my_printf(cosnt char *fmt, ...)
需要注意的地方:
C語言變參使用
c語言中有很多變參的使用,例如printf 的原型是int printf const char fmt,那麼c語言是如何解析和處理這些變參的呢?下面進行簡單的總結 c語言中定義了下面的一些巨集,專門用來處理變參 va start va list ap,char fmt va arg va list ...
C語言(變參函式)
c語言雖然沒有c 的函式過載特性,但也可以實現變參,但要保證第乙個引數資訊的完整性。拓展 定義變參函式時,第乙個引數一般是字串,攜帶後續變參的型別和數量資訊,變參使用三點來表示,如 void sumup const char info,再使用va list va start va arg 和va e...
C語言變參,記錄
由於在 c語言中沒有函式過載 解決不定數目函式引數問題變得比較麻煩 即使採用 c 如果引數個數不能確定 也很難採用函式過載 對這種情況 有些人採用指標引數來解決問題.uhmm 用到的變參地方 用的原因 1,sql 語言必須用常量2,sql語言格式不相同,引數個數不相同使用a dyw mysql nu...