測試環境: vs2008
1、可變引數列表
為什麼需要可變引數呢?
在函式原型中,列出了函式期望接受的引數,原型只能顯示固定數目的引數,如果函式原型列出的引數與可呼叫引數不匹配或數目不一樣,程式將無法執行。例如,我們想要求一系列值的平均值,這裡的一系列的數目是不確定的,如果這些值儲存於陣列中,這個任務就很簡單了,但如果我們不用陣列,想要直接呼叫,就需要可變引數了。
什麼是可變引數?
c語言中的可變引數是通過將函式是按為可變引數的形式,可以是得函式接受乙個以上的任意多個引數(不固定)。
2、stdarg巨集
可變引數列表是通過巨集來是實現的,這些巨集定義於 stdarg.h 有檔案,這個有檔案宣告了三個巨集———— va_start, va_arg和va_end,和乙個型別 va_list。
#elif defined(_m_ix86)
#define _intsizeof(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define _crt_va_start(ap,v) ( ap = (va_list)_addressof(v) + _intsizeof(v) )
#define _crt_va_arg(ap,t) ( *(t *)((ap += _intsizeof(t)) - _intsizeof(t)) )
#define _crt_va_end(ap) ( ap = (va_list)0 )
3、可變引數三個巨集的使用
初始化函式宣告了乙個名叫 va_arg 的變數, 它用於訪問未確定的部分,這個變數通過 va_start 來初始化。
它的裡邊有兩個引數:
1、va_list變數的名字
2、省略號前最後乙個有名字的引數。
初始化時把va_arg變數設定為可變引數部分的第乙個引數。
訪問後邊引數
這裡需要 va_arg ,va_arg返回這個引數的值,並使用 va_arg指向下乙個可變引數。
它的裡邊也有兩個引數:
1、va_list變數
2、引數列表中下乙個引數的型別
用va_end巨集來釋放此前動態分配的記憶體
4、看乙個例子
接下來我們來看乙個例子來理解下可變引數的用法。
//求任意個引數的平均值
#include
#include
int max(int n_values, ...)
}return max;
}int main()
5、可變引數的限制
可變引數必須從頭到尾逐個訪問,如果你在訪問了幾個可變引數之後想半途終止,這是可以的,但是,如果你想一開始就訪問列表中間的引數,那是不行的。
* 引數列表中至少有乙個命名引數。如果連乙個命名引數都沒有,就無法使用va_start
* 這些巨集是無法直接判斷實際存在引數的變數。
* 這些巨集無法判斷每個引數的是型別。
* 如果在 va_arg 中指定了錯誤的型別,那麼其後果是不可**的。
可變引數的建立是先開闢一塊空間,建立好最右邊的變數之後,然後在根據類別有上往下建立,因此不能直接訪問中間變數,可以訪問一半終止。
可變引數列表
模擬實現printf函式 va list是在c語言中解決變參問題的一組巨集,所在標頭檔案 include 用於獲取不確定個數的引數 va start,函式名稱,讀取可變引數的過程其實就是在堆疊中,使用指標,遍歷堆疊段中的引數列表,從低位址到高位址乙個乙個地把引數內容讀出來的過程 va arg,這個巨...
可變引數列表
小二,上 class a public class varargs two param static void twostringparam string a,string b three param 參照上兩種寫法,一直往後面加。是不是感覺很憂傷 幸好這不是真的。string.a static v...
可變引數列表
c語言中可變引數列表是通過巨集來實現的,這些巨集包含在stdarg.h標頭檔案中,該標頭檔案定義了va list型別和三個巨集 va start va arg va end。用法 首先宣告乙個va list型別的變數,使用va start巨集進行初始化,va start巨集的第乙個引數是該va li...