用va list實現變參函式

2021-06-18 00:55:29 字數 1611 閱讀 8788

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...