#include#include#include/***編寫可變長(zhǎng)參數(shù)列表的函數(shù)案例*/
/*
void?minprintf(char?*fmt,...)這個(gè)函數(shù)只處理格式字符串和參數(shù),格式的轉(zhuǎn)換則通過printf函數(shù)實(shí)現(xiàn)
省略號(hào)表示參數(shù)的數(shù)量和類型是可變的,省略號(hào)只能出現(xiàn)再參數(shù)表的尾部,minprintf不需要像printf
函數(shù)返回實(shí)際輸出的字符數(shù),所以可以返回類型設(shè)置為void
編寫minprintf關(guān)鍵在于如何處理一個(gè)甚至連名字都沒有的參數(shù)表,標(biāo)準(zhǔn)頭文件中包含一組宏定義
,他們對(duì)如何遍歷參數(shù)表進(jìn)行了定義,該頭文件的實(shí)現(xiàn)因不同的機(jī)器而不同,但提供的接口都是一致的。
va_list類型用于聲明一個(gè)變量,該變量依次引用各參數(shù),在函數(shù)minprintf中,將該變了成為ap,意思是參數(shù)
指針,在使用ap前,該宏必須先被調(diào)用一次,參數(shù)表至少包含一個(gè)有名參數(shù),va_start將最后一個(gè)有名參數(shù)
做為起點(diǎn),每次調(diào)用,va_arg,該參數(shù)返回一個(gè)參數(shù),并將ap指向下一個(gè)參數(shù),va_arg使用一個(gè)類型名來(lái)決定
返回對(duì)象的類型,指針移動(dòng)的步長(zhǎng),最后必須在函數(shù)返回之前調(diào)用va_end,以便完成一些必要的清理工作。*/
void?minprintf(char?*fmt,...)
{
????va_list?ap;
????char?*p,*sval;
????double?dval;
????int?ival;
????va_start(ap,fmt);
????for(p=fmt;*p;p++)
????{
????????if(*p!='%')
????????{
????????????putchar(*p);
????????????continue;
????????}
????????switch?(*++p)
????????{
????????????case?'d':
????????????????ival=va_arg(ap,int);
????????????????printf("%d",ival);
????????????????break;
????????????case?'f':
????????????????dval=va_arg(ap,double);
????????????????printf("%f",dval);
????????????????break;
????????????case?'s':
????????????????for(sval=va_arg(ap,char?*);*sval;sval++)
????????????????{
????????????????????putchar(*sval);
????????????????}
????????????????break;
????????????default?:
????????????????putchar(*p);
????????????????break;
????????}
????}
????va_end(ap);
}
int?sum(int?m,...)
{
????va_list?ap;//依次指向每個(gè)無(wú)名參數(shù)
????va_start(ap,m);//將ap指向第一個(gè)無(wú)名參數(shù)
????int?sum=0;
????while(m--)
????{
???????sum+=va_arg(ap,int);
????}
????va_end(ap);//結(jié)束時(shí)候的清理工作
????return?sum;
}
int?main(int?argc,char?*argv[])
{
??minprintf("%dhao%shao%f",10,"asda",20.1);
??printf("%d",sum(3,10,20,32));
}