2、 va函數的定義和va宏
C 語言支持va函數,做爲C語言的擴展--C++一樣支持va函數,但在C++中並不推薦使用,C++引入的多態性一樣能夠實現參數個數可變的函數。不過, C++的重載功能畢竟只能是有限多個能夠預見的參數個數。比較而言,C中的va函數則能夠定義無窮多個至關於C++的重載函數,這方面C++是無能爲力 的。va函數的優點表如今使用的方便性和易用性上,可使代碼更簡潔。C編譯器爲了統一在不一樣的硬件架構、硬件平臺上的實現,和增長代碼的可移植性,提供 了一系列宏來屏蔽硬件環境不一樣帶來的差別。
ANSI C標準下,va的宏定義在stdarg.h中,它們有:va_list,va_start(),va_arg(),va_end()。
// 例2:求任意個天然數的平方和:
int SqSum(int n1, ...){va_list arg_ptr;int nSqSum = 0, n = n1;va_start(arg_ptr, n1);while (n > 0){ nSqSum += (n * n); n = va_arg(arg_ptr, int);}va_end(arg_ptr);return nSqSum;}// 調用時int nSqSum = SqSum(7, 2, 7, 11, -1);
可變參數函數的原型聲明格式爲:
type VAFunction(type arg1, type arg2, ... );
參數能夠分爲兩部分:個數肯定的固定參數和個數可變的可選參數。函數至少須要一個固定參數,固定參數的聲明和普通函數同樣;可選參數因爲個數不肯定,聲明時用 "... "表示。固定參數和可選參數公同構成一個函數的參數列表。
藉助上面這個簡單的例2,來看看各個va_xxx的做用。
va_list arg_ptr:定義一個指向個數可變的參數列表指針;
va_start(arg_ptr, argN):使參數列表指針arg_ptr指向函數參數列表中的第一個可選參數,說明:argN是位於第一個可選參數以前的固定參數,(或者說,最後一個 固定參數;...以前的一個參數),函數參數列表中參數在內存中的順序與函數聲明時的順序是一致的。若是有一va函數的聲明是void va_test(char a, char b, char c, ...),則它的固定參數依次是a,b,c,最後一個固定參數argN爲c,所以就是va_start(arg_ptr, c)。
va_arg(arg_ptr, type):返回參數列表中指針arg_ptr所指的參數,返回類型爲type,並使指針arg_ptr指向參數列表中下一個參數。
va_copy(dest, src):dest,src的類型都是va_list,va_copy()用於複製參數列表指針,將dest初始化爲src。
va_end (arg_ptr):清空參數列表,並置參數指針arg_ptr無效。說明:指針arg_ptr被置無效後,能夠經過調用va_start()、 va_copy()恢復arg_ptr。每次調用va_start() / va_copy()後,必須得有相應的va_end()與之匹配。參數指針能夠在參數列表中隨意地來回移動,但必須在va_start() ... va_end()以內。架構