變參函數(shù)的實(shí)現(xiàn) 收藏相對(duì)于固定參數(shù)的函數(shù),變參函數(shù)的可用性無(wú)疑是更好的,。我們最常用的變參函數(shù)包括scanf和printf,。剛剛接觸到變參函數(shù)的時(shí)候,我覺(jué)得這太神奇了,,它并不知道我要輸入什么類型的數(shù)據(jù),,要輸入多少個(gè)數(shù)據(jù),卻能完美地處理,。其實(shí),,可變參數(shù)機(jī)制實(shí)現(xiàn)起來(lái)是相當(dāng)容易的(在stdarg.h的基礎(chǔ)上),而且,,它的作用并沒(méi)有想象中的那么神奇,。 可變參數(shù)機(jī)制并不能獲取某次輸入的所有參數(shù)的個(gè)數(shù),也不能自己確定每一個(gè)輸入?yún)?shù)的類型,。嗯,,沒(méi)錯(cuò),看上去printf和scanf就能知道每次輸入的參數(shù)個(gè)數(shù)和每個(gè)參數(shù)的類型,。其實(shí),,仔細(xì)想一想就會(huì)發(fā)現(xiàn)printf和scanf沒(méi)這個(gè)本事,輸入的參數(shù)個(gè)數(shù)和每個(gè)參數(shù)的類型是使用者在format內(nèi)容中,,通過(guò)%模式等告訴編譯器的,。光是這么說(shuō)可能不夠取信于人,以簡(jiǎn)化的printf為例,,讓我們看一段K&R中的例程吧:
可以看出,,printf處理可變參數(shù)的關(guān)鍵就在于它的參數(shù)char *fmt。注意程序中的for循環(huán),,指針p正是一次次地根據(jù)fmt中的提示(在這個(gè)簡(jiǎn)化的例子中是%)經(jīng)由switch分支來(lái)確定下一個(gè)參數(shù)的類型和有效參數(shù)的個(gè)數(shù),。 所以說(shuō),可變參數(shù)不是萬(wàn)能的,,它只是一種很normal的機(jī)制,,不過(guò)正是先驅(qū)們那化腐朽為神奇的想象力,借由這種normal的機(jī)制實(shí)現(xiàn)了神奇而又令人詬病的scanf和printf函數(shù),。一般而言,,除了像printf一樣,在函數(shù)中實(shí)現(xiàn)一個(gè)特殊的format之外,一些可變參數(shù)中的參數(shù)類型都是一致的(比如說(shuō)只可能都是int)函數(shù),,則會(huì)在之前的固定參數(shù)中用一個(gè)參數(shù)指出可變參數(shù)的個(gè)數(shù)或是類型,。下面是一個(gè)C Primer Plus中的例程:
可以看出,函數(shù)sum中的固定參數(shù)lim指出了可變參數(shù)的個(gè)數(shù),。 以上介紹了可變參數(shù)機(jī)制實(shí)現(xiàn)的兩種過(guò)程:自定義format和前置指示標(biāo)志,。接下來(lái)就會(huì)詳細(xì)解釋在C語(yǔ)言中如何具體實(shí)現(xiàn)可變參數(shù)機(jī)制。從兩個(gè)例程可以看出,,有四個(gè)宏是至關(guān)重要的:
va_list:一個(gè)char鏈表(實(shí)際上應(yīng)該是一個(gè)連續(xù)的內(nèi)存塊,,像數(shù)組一樣),在使用時(shí)表現(xiàn)為一個(gè)指向char類型的指針,; va_start:初始化va_list,。通過(guò)最后的固定參數(shù)實(shí)現(xiàn)對(duì)可變參數(shù)初始位置的定位,并為va_list分配內(nèi)存,,將可變參數(shù)復(fù)制該內(nèi)存塊中,,使va_list指向該內(nèi)存塊的初始位置; va_arg:通過(guò)移動(dòng)指針va_list獲取由參數(shù)Type指定的變量并返回該變量,。 va_end:釋放va_list擁有的內(nèi)存塊所占據(jù)的內(nèi)存空間,。 看,一切不就一清二楚了嗎,?不過(guò),,還有如下幾個(gè)問(wèn)題還需要特別注意一下: 1> C標(biāo)準(zhǔn)規(guī)定實(shí)現(xiàn)可變參數(shù)機(jī)制的函數(shù)至少要有一個(gè)固定參數(shù)。從上面的討論可以看出,,這無(wú)論是從語(yǔ)法上還是實(shí)現(xiàn)上都是必須的。 2> 隱式類型轉(zhuǎn)換不可用,。比如說(shuō),,va_arg指定了類型是double,若傳入的是int的變量10就會(huì)出錯(cuò),。 3> C語(yǔ)言的整型提升原則,。也就是說(shuō),在va_arg中獲取float和double使用的Type都是double,,而獲取char,、short和int使用的Type都是int。 函數(shù)指針不可用,,除非用typedef定義過(guò),。發(fā)表于 @ 2008年11月29日 23:27:00 | 評(píng)論( 0 ) | 舉報(bào)| 收藏 舊一篇:typedef和#define | 新一篇:關(guān)鍵字class與struct
|
|