c語言中的可變引數程式設計

2021-09-08 09:32:42 字數 1754 閱讀 6962

在c語言中使用變長引數最常見的就是下面兩個函式了:

int printf(const

char *format, ...);

int scanf(const

char *format, ...);

那他們是怎樣實現支援變成引數的呢?在使用變長引數的函式(這裡假設是func)實現部分其實用到了stdarg.h裡面的多個巨集來訪問那些不確定的引數,它們分別是:

void

va_start(va_list ap, last);

type va_arg(va_list ap, type);

void

va_end(va_list ap);

假設lastarg是func的最後乙個具名引數,即在func函式定義中...之前的那個引數(在printf中lastarg是format),在func中首先定義乙個變數:

va_list ap

這個變數以後會依次指向各個可變引數。ap在使用之前必須用巨集va_start初始化一次,如下所示:

va_start(ap, lastarg);

其中lastarg是func中的最後乙個具名引數。然後就可以用va_arg來獲得下乙個不定引數(前提是知道這個不定引數的型別type):

type next = va_arg(ap, type)

最後就是用巨集va_end來清理現場。

下面我們來自己實現乙個可變引數的函式:

1 #include 2 #include 3

4void func(char *fmt, ...)

526 fmt ++;27}

28va_end(ap);29}

3031

int main ( int argc, char *ar** )

32 /*

---------- end of function main ----------

*/

輸出結果:

10

shello

可以看到上面的程式完成按我們的意願實現了變長引數的訪問,通過前面的fmt來控制下乙個不定引數的型別。那這三個巨集是怎樣實現對不定引數訪問的呢?下面來看看它們是怎麼實現的:

va_list實際就是乙個指向各個不定引數的指標,由於引數的型別是不確定的,所以可以定義va_list為void *或者char *型別,即

#define va_list void *

va_start就是將va_list指向函式最後乙個具名引數lastarg後面的位置,這個位置就是第乙個不定引數。

#define va_start(ap, lastarg) \(ap = (va_list)&lastarg + sizeof(lastarg))

va_arg獲取當前不定引數的值,根據當前引數的型別的大小移動指標指向下乙個不定引數。

#define va_arg(ap, type) \(*(type *)((ap += sizeof(type)) - sizeof(type)))

va_end將指標清0。

#define va_end(ap) (ap=(va_list)0)

本質上其實就是靠前面lastarg來控制不定引數的型別,va_list變數來指向不定引數的位址,然後根據lastarg乙個乙個的獲取不定引數。

C語言中的可變引數

1 需要標頭檔案 include 2 函式定義 void logcmd int arg0,void logcmd char arg0,3 解析 i 數字型別 void logcmd int n,其中n表示引數的個數,n之後才是真正的引數。呼叫如 logcmd 0 logcmd 1,9 logcmd ...

C語言中可變引數的用法

c語言中可變引數的用法 我們在c語言程式設計中會遇到一些引數個數可變的函式,例如printf 這個函式,它的定義是這樣的 int printf const char format,它除了有乙個引數format固定以外,後面跟的引數的個數和型別是 可變的,例如我們可以有以下不同的呼叫方法 printf...

C語言中的可變引數函式

先來個例子,後面再說明 上面的程式我在vc6.0編譯通過 現在說一下可變引數的用法 第一步 函式宣告 functionname char format,第二步 定義va list 變數 ap 第三步 使ap和引數列表關聯起來va start ap,format 第四步 你可以按照引數列表即forma...