可變參數的使用

可變參數列表式通過宏來實現的,宏定義在 stdarg.h頭文件中,該頭文件聲明瞭一個類型va_list 和三個宏 。
 
提供的三個宏分別如下:

void va_start(va_list ap, last);

type va_arg(va_list ap, type);

void va_end(va_list ap);

這種隱式的數據類型是va_list 

上面宏的前綴va表示variable argument,即可變參數的意思。變量ap專門用來記錄獲取可變參數。下面依次介紹三個宏的意義和用法。

[*] void va_start( va_list ap, last)

        last爲函數形參中"..."前的最後一個形參名字,宏va_start用於根據last的位置(或指針)來初始化變量ap,以供宏ar_arg來依次獲得可變參數的值。變量ap在被va_argva_end使用前,必須使用va_start初始化。

[*] type va_arg(va_list ap, type)

       va_arg宏用來獲得下一個參數的值,type爲該參數的類型,它的參數ap必須被va_start初始化,通過該宏後,返回參數值並使用ap指向下一個參數,以供va_arg再次使用。如果沒有下一個參數時調用va_argarg指定的類型不兼容時,會產生可知的錯誤。

[*]void va_end(va_list ap)

         va_endva_start必須要同一函數裏面對稱使用,調用va_start(ap,last)ap得到初始化,在完成參數處理後,需要調用va_end(ap)釋放”ap   

 

下面我們來探討如何寫一個簡單的可變參數的C函數.寫可變參數的
C函數要在程序中用到以下這些宏:
void va_start( va_list arg_ptr, prev_param );

type va_arg( va_list arg_ptr, type );

void va_end( va_list arg_ptr );
va在這裏是variable-argument(可變參數)的意思.
這些宏定義在stdarg.h中,所以用到可變參數的程序應該包含這個
頭文件.下面我們寫一個簡單的可變參數的函數,改函數至少有一個整數
參數,第二個參數也是整數,是可選的.函數只是打印這兩個參數的值.
void simple_va_fun(int i, ...)
{
va_list arg_ptr;
int j=0;

va_start(arg_ptr, i);
j=va_arg(arg_ptr, int);
va_end(arg_ptr);
printf("%d %d\n", i, j);
return;
}
我們可以在我們的頭文件中這樣聲明我們的函數:
extern void simple_va_fun(int i, ...);
我們在程序中可以這樣調用:
simple_va_fun(100);
simple_va_fun(100,200);
從這個函數的實現可以看到,我們使用可變參數應該有以下步驟:
1)首先在函數裏定義一個va_list型的變量,這裏是arg_ptr,這個變
量是指向參數的指針.
2)然後用va_start宏初始化變量arg_ptr,這個宏的第二個參數是第
一個可變參數的前一個參數,是一個固定的參數.
3)然後用va_arg返回可變的參數,並賦值給整數j. va_arg的第二個
參數是你要返回的參數的類型,這裏是int型.
4)最後用va_end宏結束可變參數的獲取.然後你就可以在函數裏使
用第二個參數了.如果函數有多個可變參數的,依次調用va_arg獲
取各個參數.
如果我們用下面三種方法調用的話,都是合法的,但結果卻不一樣:
1)simple_va_fun(100);
結果是:100 -123456789(會變的值)
2)simple_va_fun(100,200);
結果是:100 200
3)simple_va_fun(100,200,300);
結果是:100 200
我們看到第一種調用有錯誤,第二種調用正確,第三種調用盡管結果
正確,但和我們函數最初的設計有衝突.下面一節我們探討出現這些結果
的原因和可變參數在編譯器中是如何處理的.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章