可變引數列表

2021-08-17 11:46:17 字數 1766 閱讀 4327

測試環境: 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...