在使用c語言程式設計的時候,函式中形式引數的數目通常是確定的,在呼叫時要依次給出與形式引數對應的所有實際引數,但在某些情況下,我們希望函式的引數個數可以根據需要來確定(例如常見的printf()函式,它的函式引數個數就是不確定的),這時我們就需要可變參函式了。
採用 ansi 標準形式時,可變參函式的原型宣告如下:
type funcname(type para1, type para2, ...)
上述函式定義形式至少需要乙個普通的形式引數,後面的省略是函式原型的一部分,表示該函式為可變參函式,type是函式返回值和形參的型別。
注意:函式引數表中的三個圓點只能放在參數列最後,即在所有普通引數之後。
為了能在可變參函式裡取得並處理不定個數的「其他引數」,需要使用標頭檔案提供的一套機制。
標頭檔案提供了乙個特殊型別va_list,在每個可變參函式的函式體裡必須定義乙個va_list型別的區域性變數,它將成為訪問由三個圓點所代表的實際引數的媒介。
下面假設某個可變參函式裡所用的va_list型別的變數的名字是vap,我們使用vap訪問實參的步驟大致如下:
1)在使用vap訪問實際引數之前,必須先用巨集va_start對這個變數初始化,如下:
va_start(vap, nnum);
nnum是可變參函式的最後乙個確定的引數,va_start使vap指向第乙個可選引數。
va_arg(vap, int);
在呼叫巨集va_arg時必須提供有關實參的實際型別(如本例中的int),這一型別也將成為這個巨集呼叫的返回值型別。
3)在使用va_arg巨集獲取了所有的實參之後,最後使用va_end巨集把vap指標清為null,如下:
va_end(vap);
我們在函式體內可以多次遍歷這些由vap代表的實參,但是都必須以va_start開始,並以va_end結尾。
3.1 demo1
需求:我們想定義乙個函式sum,該函式可以有任意多個整型引數,函式sum最終返回這些引數的和。
我們應該將sum函式定義為乙個只有乙個普通引數、並具有可變長度參數列的函式,這個函式的頭部應該是(函式原型與此類似):
int sum(int n, ...)
實際上我們要求在呼叫該函式時,第乙個引數n代表想要求和的引數個數,而其餘的引數為將要進行求和的引數。
完整**(variable_arg.c)如下:
#include #include int sum(int nnum, ...)
va_end(vap);
return nsum;
}int main()
編譯後,執行該程式,執行結果如下:
上述結果顯示可變參函式sum滿足了我們的需求。
3.2 demo2
需求:使用可變參函式,將可變個數的字串引數列印出來。
我們應該將demo函式定義為乙個只有乙個普通引數、並具有可變長度參數列的函式,這個函式的頭部應該是(函式原型與此類似):
int demo(char* msg, ...)
我們在呼叫該函式時,會將除msg外的其餘的引數列印出來,同時需要注意,在實際呼叫這個函式時,要通過一定的方法指明實際引數的個數,例如把最後乙個引數置為空字串(本例採用此種方式)或其他的方式。完整**(variable_arg2.c)如下:
#include #include #include /* 函式原型宣告,至少需要乙個確定的引數,注意括號內的省略號*/
int demo(char*, ...);
int main()
/* ansi標準形式的宣告方式,括號內的省略號表示可選引數 */
int demo(char *msg, ...)
printf("parameter #%d is: %s\n", argno, para);
argno++;
}/* 將argp置為null */
va_end(argp);
return 0;
}
編譯後,執行該程式,執行結果如下:
上述結果顯示可變參函式demo滿足了我們的需求。
C語言中變參函式傳參的實現示例
目錄 近期在看一本書,叫做 嵌入式c語言自我修養 寫的內容對我幫助很大,是一本好書。在第6章 c編譯器擴充套件語法精講一節,這本書給出了一些變參函式的例子 1.變參函式初體驗 include void print num int count,int main void 上面的 很好理解 定義乙個變參...
C語言的可變參函式
可變參函式,顧其名而思義,就是該函式的引數數目不固定,例如我們的格式化輸出函式 int printf const char fmt,這個函式的 引數就代表它是個可變參的函式。這個函式第乙個引數一定是乙個字串,通過字串中的 d s 等等來對應後面的引數數量,這樣以來就可以正確解析函式的引數。實現可變參...
C語言可變參函式的實現
函式是大多數程式語言都實現的程式設計要素,呼叫函式的實現原理就是 執行跳轉 引數傳遞。對於執行跳轉,所有的cpu都直接提供跳轉指令 對於引數傳遞,cpu會提供多種方式,最常見的方式就是利用棧來傳遞引數。c語言標準實現了函式呼叫,但是卻沒有限定實現細節,不同的c編譯器廠商可以根據底層硬體環境自行確定實...