實現c語言中的可變引數函式

2021-07-22 19:34:38 字數 2023 閱讀 1672

c語言程式設計中有時會遇到一些引數個數可變的函式,例如printf()函式,其函式原型為:

int printf( const char* format, ...);
它除了有乙個引數format固定以外,後面跟的引數的個數和型別是可變的(用三個點「…」做引數佔位符),實際呼叫時可以有以下的形式:

printf("%d",i); 

printf("%s",s);

printf("the number is %d ,string is:%s", i, s);

乙個簡單的可變引數的c函式。該函式至少有乙個整數引數,其後佔位符…,表示後面引數的個數不定。在這個例子裡,所有的輸入引數必須都是整數,函式的功能只是列印所有引數的值。函式**如下:

#include 

#include

void ******_va_fun(int start, ...)

while(nargvalue != -1);

} int main(int argc, char* argv)

下面解釋一下這些**。從這個函式的實現可以看到,我們使用可變引數應該有以下步驟:

⑴由於在程式中將用到以下這些巨集:

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中,所以用到可變引數的程式應該包含這個標頭檔案。

⑵函式裡首先定義乙個va_list型的變數,這裡是arg_ptr,這個變數是儲存引數位址的指標.因為得到引數的位址之後,再結合引數的型別,才能得到引數的值。

⑶然後用va_start巨集初始化⑵中定義的變數arg_ptr,這個巨集的第二個引數是可變引數列表的前乙個引數,即最後乙個固定引數。

⑷然後依次用va_arg巨集使arg_ptr返回可變引數的位址,得到這個位址之後,結合引數的型別,就可以得到引數的值。

⑸設定結束條件,這裡的條件就是判斷引數值是否為-1。注意被調的函式在呼叫時是不知道可變引數的正確數目的,程式設計師必須自己在**中指明結束條件。

附:vprintf的用法

在實際專案中,很多時候都會對printf進行一層封裝,來實現不同級別的列印。對於這種需求,一般有兩種方式可以實現。

一.使用巨集#define來實現。

如:

#define dbg_error 1

#define dbg_warn 2

#define log_printf(level, format, ...) \

do while (0)

#define dbg_error 1

#define dbg_warn 2

#define log_printf(level, format, arg...) \

do while (0)

二.借助vprintf實現

原型:int

vprintf(const

char *format, va_list arg);

標頭檔案:

例子:

#include 

#include

#define dbg_error 1

#define dbg_warn 2

void log_printf(int level, const char *format, ...)

else

if (level & dbg_warn)

va_end(args);

}

參考文章:

C語言中可變引數函式的實現

c語言的可變引數函式的實現需要使用標頭檔案stdarg.h,在該標頭檔案中定義了乙個變數型別va list和三個巨集va start va arg va end 下面將在 中講解這幾個巨集的使用方法。第一種方法是在函式內部手動指定可變引數的型別。首先需要知道可變引數的個數,並作為第乙個引數傳入。由於...

C語言中可變引數函式實現原理

c函式呼叫的棧結構 可變引數函式的實現與函式呼叫的棧結構密切相關,正常情況下c的函式引數入棧規則為 stdcall,它是從右到左的,即函式中的最右邊的引數最先入棧。例如,對於函式 void fun int a,int b,int c 其棧結構為 0x1ffc d 0x2000 a 0x2004 b ...

C語言中可變引數函式實現原理

說的非常詳細,但是有部分口誤,希望只吸取精華 c函式呼叫的棧結構 可變引數函式的實現與函式呼叫的棧結構密切相關,正常情況下c的函式引數入棧規則為 stdcall,它是從右到左的,即函式中的最右邊的引數最先入棧。例如,對於函式 void fun int a,int b,int c 其棧結構為 0x1f...