可變引數函式

2021-06-22 14:56:27 字數 1983 閱讀 2509

一、什麼是可變引數

我們在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函式

先看例子程式。該函式至少有乙個整數引數,其後是佔位符…,表示後面引數的個數不定. 

在這個例子裡,所有的輸入引數必須都是整數,函式的功能是列印所有引數的值. 

函式**如下: 

//示例**1:可變引數函式的使用 

#include "stdio.h" 

#include #include "stdarg.h"

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

while(nargvalue != -1);

return;

} int main(int argc, char* argv)

從這個函式的實現可以看到,我們使用可變引數應該有以下步驟: 

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

typedef char * va_list; //字串指標

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。注意被調的函式在呼叫時是不知道可變引數的正確數目的,程式設計師必須自己在**中指明結束條件。至於為什麼它不會知道引數的數目,讀者在看完下面這幾個巨集的內部實現機制後,自然就會明白。

三、巨集定義

typedef char * va_list; //字串指標

#define _intsizeof(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

#define va_start(ap,v) ( ap = (va_list)&v + _intsizeof(v) )//獲取第乙個可變引數的起始記憶體位址

#define va_arg(ap,t) ( *(t *)((ap += _intsizeof(t)) - _intsizeof(t)) )//根據指定的引數型別取得本引數的值,並且把指標調到下乙個引數的起始位址。 

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

可變引數函式

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 list 用來儲存巨集va start va arg和v...

可變引數函式

stdarg.h是 c語言中c標準函式庫的 標頭檔案,stdarg是由standard 標準 arguments 引數 簡化而來,主要目的為讓函式能夠接收可變引數。stdarg.h 資料型別 型別名稱 描述 va list 用來儲存巨集va arg與巨集va end所需資訊 巨集名稱 描述va st...

函式可變引數

cpp view plain copy print include include using namespace std 求若干數的平方和 第乙個引數是引數的個數 double pingfangsum inta,va end var arg 清空引數列表,並置引數指標arg ptr無效。retur...