http://www.cnblogs.com/hnrainll/archive/2011/07/06/2099494.html
http://baike.baidu.com/link?url=LVqNiDgwI3huqGZZwD8PR_iN5TTfUe-zKr6BX380Pm6i5tu3dFGdyT-p2TaV0DzLnRAZ10U5ZbwIYcHS7SKJ-a
http://blog.chinaunix.net/uid-25572546-id-2183161.html
#include <stdio.h>#include <stdarg.h>//模擬實現系統提供的printf函數int vpf(char*fmt,...){va_list ap;int cnt; va_start(ap,fmt);//第一個參數為指向可變參數字符指針的變量,第二個參數是可變參數的第一個參數,通常用于指定可變參數列表中參數的個數cnt=vprintf(fmt,ap); va_end(ap);//將存放可變參數字符串的變量清空return(cnt);}int main(void){int inumber=30;float fnumber=90.0;char* string="abc";vpf("%d/n%f/n%s/n",inumber,fnumber,string);return 0;}
http://blog.csdn.net/jiqiren007/article/details/5935125
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*
下面繼續解析上面的三個宏:
va_start(va_list ap, char*fmt)其中ap是va_list類型的,即可變參數列表;而fmt就是printf等類似函數的參數,指明參數的類型等,例如常見的有:%d%s%c%f等等
va_list()操作進行后的效果是:使得ap指向fmt后面的參數列表,即"...".C語言函數參數是從右向左壓棧的
這個操作要在其他兩個操作前面執行
va_arg(va_list ap, Type)在執行完va_start()操作后,ap就指向了變參的列表,這個時候就可以對變參列表進行操作了,是通過對ap進行操作實現的,因為此時ap指向變參列表
va_arg(va_list ap, Type)的結果是這樣的:執行完這個操作后,首先返回ap當前指向的參數;然后ap向后移動,執行下一個參數;因此va_arg()是要循環調用的,直到所有參數都獲得
Type是當前參數的類型
va_end(va_list ap)當上面操作進行完后,ap不再使用了,需要調用va_end()操作將ap給清空
根據上面的描述,在C語言中處理變參的過程大概是這樣的:
定義va_list 變量,用來指向參數列表調用va_start()操作,將定義的va_list變量指向變參列表調用va_arg()操作,獲得每個參數調用va_end()操作,清空va_list變量從上面的過程可以看到,在執行第三步的時候有點麻煩,比如事先根本不知道參數的類型等,這樣調用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了:
int my_printf(cosnt char *fmt, ...)
{
va_list ap; //定義va_list 變量
va_start(ap, fmt); //讓ap指向變參...
int n = vprintf(fmt, ap); //調用vprintf進行輸出
return n; //返回輸出的字符數,printf返回值是int
}
需要注意的地方:
在使用C語言的變參時,需要將變參(即...)放在最后一個參數的位置;并且變參前面至少要有一個普通的參數新聞熱點
疑難解答