c++中有函式過載這種方法,以供我們呼叫時要可以不確定實參的個數,其實c語言也可以,而且更高明!
我們在stdio.h中可以看到printf()函式的原型:
int printf(char * format,...)
事實上,我們如果要寫這樣的函式也可以類似的寫,那麼在定義函式時用上這個符號「...」,它叫佔位符,喊它「三個點」也可以,只要你願意!那麼我可以這樣定義我的函式:
fun(int a,...)
只要上課認真聽了的同學(傻瓜除外)都知道,這是個空函式,它是什麼都不做的,光這樣寫還不行的,具體應該怎樣定義呢?
且聽我介紹3個小東東:
1、va_list
2、va_arg()
3、va_start()
在學習這3個小東東之前,我們先回憶一下,c語言是怎麼操作檔案時,是怎麼樣處理記憶體中的資料的呢?學習檔案操作時,我們提到了「流」的概念,我們用指標指向資料所在的記憶體位址,再乙個乙個的操作。
學習指標時,我們知道有函式指標這個東東,不是指標函式而是函式打針哦!(呵呵,我的同學如果還記得就當複習一下,不要嫌我囉嗦^_^)。我們記得程式在執行時,會將函式儲存到記憶體中去。現在深入的講一點點,儲存函式時,引數傳遞的過程是怎樣實現的呢?所謂的形式引數(區域性變數)實質上又是什麼呢?把這些問題連起來想想,想通了,你的思維勢如破竹!
在呼叫函式時,程式同樣會把實參傳入,在函式儲存區儲存起來,如果有很多引數,將一起儲存起來。
這時候就要用到va_list了,這是個型別定義,我們可以把它理解成乙個指標,它指向第乙個引數的位址。
如果,我們這樣定義: va_list pp;
則pp就是這樣一種變數,它是指向所有引數中的第乙個引數的。它不同於一般的指標變數,它是個復合變數,什麼是復合變數啊?結構體型別的嘛,呵呵。如果a是第乙個引數,能不能寫成 pp=a呢?
假設我定義了char d="ruixin",e="gelin";我要把e的值賦給d,能不能寫成d=e呢?得用strcpy(),是吧!呵呵,一樣的道理,這兒我們也用乙個函式來實現,它就是va_start();
如果這樣寫:va_start(pp,a);
那麼pp就指向第乙個引數a了,並且可得到a的型別int。
可以這樣寫:va_arg(pp,型別),這樣pp就指向乙個引數,並且可以得到那個引數的型別了。
注意!型別非常重要,學過指標的都應該清楚,指標的型別如果弄錯的話,位置正確,取出來的數可能也是亂七八糟的。
下面我們看乙個簡單的例子:
#include
#include
void fun(int a,...)
va_list pp;
int n=1;//使用n計量引數個數
va_start(pp,a);
doprintf("第%d個引數=%d\n",n++,a);
a=va_arg(pp,int);//使pp指向下乙個引數,將下乙個引數的值賦給變數a
while (a!=0);//直到引數為0時停止迴圈
va_end(pp);//將pp的值置為null
main()
fun(20,40,60,80,0);
注意!一定要有上面兩個檔案包含命令,因為程式中用到的那3個小東東都在那個檔案裡。其實真正意義上應該說那是函式,實質上那不過是兩個巨集,呵呵。
C語言中實現引數個數可變的函式
以前一直不知道原來c語言也有引數個數可變的函式。1 採用ansi標準形式時,引數個數可變的函式的原型宣告是 type funcname type para1,type para2,這種形式至少需要乙個普通的形式引數,後面的省略號不表示省略,而是函式原型的一部分。type是函式返回值和形式引數的型別。...
c語言中的不定引數
在採用c語言程式設計時,函式中的形式引數數目通常是確定的,在呼叫的時候要依次給出與形式引數對應的所有實際引數,但在某些情況下希望函式的引數個數可以根據需要確定,如printf,scanf函式等,c編譯器提供了一系列處理這種情況的巨集,以遮蔽不同的硬體平台造成的差異,增加程式的可移植性,這些巨集包括v...
C語言中的不定引數
1,最近剛剛知道c語言還有不定引數這麼個東東。2,解決方法 三個巨集的使用va arg va start 和va end 上述的巨集原型如下所示 type va arg va list argptr,type void va end va list argptr void va start va l...