va_list 是c語言中解決變參問題的一組巨集。
1.api介紹:
標頭檔案:
#include
下面是實現變參函式的一組巨集(macro):
void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_end(va_list ap);
void va_copy(va_list dest, va_list src);
2.具體介紹:
void va_start(va_list ap, last);
va_start用於初始化變參結構ap,其中va_list是與變參列表相關的結構,裡面儲存著變參列表的資訊包括變參列表的指標。
last是變參函式的可變引數列表的前乙個引數,用於確定可變引數的記憶體位址;
type va_arg(va_list ap, type);
va_arg取出當前的引數用於返回,並且把變參列表指標指向下乙個引數。其中ap是經過va_start初始化的變參結構,type是變參的型別。
void va_end(va_list ap);
va_end用於結束對可變引數的獲取,釋放相應的資源,將ap清零。va_end和va_start成對使用。
void va_copy(va_list dest, va_list src);
用於複製變參結構。由於具體實現不同,變參結構本身或是結構裡面的引數時指標,而簡單的賦值操作會造成淺拷貝,
當其中乙個結構的指標被釋放空間的時候(va_end釋放空間),另乙個結構的指標會成為野指標,可能就會出問題,所以對於va_list型的變數來說,禁止直接賦值(=),要用va_copy進行拷貝。
3.用法:
a.首先在函式裡定義一具va_list型的變數:
b.然後用va_start巨集初始化變數剛定義的va_list變數,這個巨集的第二個引數是第乙個可變引數的前乙個引數,是乙個固定的引數。
c.然後用va_arg返回可變的引數,va_arg的第二個引數是你要返回的引數的型別。如果函式有多個可變引數的,依次呼叫va_arg獲取各個引數。
d.最後用va_end巨集結束可變引數的獲取。
4.例子:
#include #include void foo(char *fmt, ...)
va_end(ap);
}
5.使用va_list應該注意的問題:
a.可變引數的型別和個數完全由程式**控制,它並不能智慧型地識別不同引數的個數和型別;
b.由於各個平台對va_list的實現可能會用不同,所以嚴格的通過va_start、va_arg、va_end、va_copy來使用va_list很有必要,不建議直接對其進行指標操作;
c.因為編譯器對可變引數的函式的原型檢查不夠嚴格,對程式設計查錯不利。不利於我們寫出高質量的**;
d.va_start,va_arg,va_end是在c89標準中定義的。va_copy是在c99標準中定義的。
參考:
C C語言中 va list 解決變參問題
va list是乙個字元指標,在 中可以理解為指向當前引數的乙個指標,這裡有幾個與va list相關的常見的函式 void va start va list ap,param 對va list變數進行初始化,將ap指標指向引數列表中的第乙個引數 type va arg va list ap,type...
變參函式實現細節
c語言的函式雖然不具備c 的多型性,但也可以接受引數不確定的情況,當然,c語言中的變參函式實際在功能上是受限的,廢話不多講,下面來看看變參函式的邊邊角角的問題。討論之前我們來看一下最熟悉的變參函式printf的原型宣告 int printf const char format,注意到,在函式中宣告其...
變參函式設計
變參函式的應用得比較少.輸出log資訊功能的函式演常會用到變參函式.什麼是變參函式?比如 printf 個數 d,總數 d a,b printf就是變參函式,因為其引數的個數不是固定的.變參函式一般用到下列巨集 va arg retrieve argument from list va end re...