valist c語言可變引數巨集

2021-07-29 16:45:06 字數 2223 閱讀 9854

va_list 是c語言中解決變參問題的一組巨集。

1.api介紹:

標頭檔案:

[cpp]view plain

copy

print?

#include 

下面是實現變參函式的一組巨集(macro):

[cpp]view plain

copy

print?

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.具體介紹:

[cpp]view plain

copy

print?

void

va_start(

va_list

ap, last);  

va_start用於初始化變參結構ap,其中va_list是與變參列表相關的結構,裡面儲存著變參列表的資訊包括變參列表的指標。

last是變參函式的可變引數列表的前乙個引數,用於確定可變引數的記憶體位址;

[cpp]view plain

copy

print?

type va_arg(

va_list

ap, type);  

va_arg取出當前的引數用於返回,並且把變參列表指標指向下乙個引數。其中ap是經過va_start初始化的變參結構,type是變參的型別。

[cpp]view plain

copy

print?

void

va_end(

va_list

ap);  

va_end用於結束對可變引數的獲取,釋放相應的資源,將ap清零。va_end和va_start成對使用。

[cpp]view plain

copy

print?

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.例子:

[html]view plain

copy

print?

#include 

<

stdio.h

>

#include <

stdarg.h

>

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標準中定義的。

va list C語言中的可變引數

c語言中有些函式使用可變引數,比如常見的int printf const char format,第乙個引數format是固定的,其餘的引數的個數和型別都不固定。但c又無法用面相物件的函式過載的概念。不過好在c語言中定義了va list,va start va arg va end 這樣一組巨集來處...

C語言可變引數巨集

歲月不饒人,這年紀大了記憶力真是差了很多。今天寫程式需要用到可變引數的巨集,可是忘了怎麼寫,這倒也沒什麼,因為我一向是不記憶這些語法細節的,反正我知道程式裡有個地方用到了這種技巧,但是可悲的是我忘了在哪個地方。搜尋?語法都忘了蒐個p呀。只好憑著印象,在自己負責的模組 中找了一圈,花了十幾分鐘才終於在...

可變引數巨集

在 gnu c 中,巨集可以接受可變數目的引數,就象函式一樣,例如 define pr debug fmt,arg.printk kern debug fmt,arg 用可變引數巨集 variadicmacros 傳遞可變參數列 你可能很熟悉在函式中使用可變參數列,如 void printf con...