C語言怎麼實現可變引數?

2021-10-08 22:26:34 字數 1914 閱讀 9814

摘要

c語言使用可變引數,需要借助巨集。這些巨集定義在stdarg.**件。stdarg.h宣告了乙個型別va_list和三個巨集va_start,va_arg,va_end。

#include

va_list v_arg;

//定義乙個型別

va_start

(v_arg,len)

;//引數列表初始化

va_arg

(v_arg,

int)

;//獲取列表中第乙個引數,第二個形參是引數型別

va_arg

(v_arg,

char);

//獲取列表中第二個引數

va_end

(v_arg)

;//用va_end巨集結束可變引數的獲取。

可變引數是由巨集實現的,但是由於硬體平台的不同,編譯器的不同,巨集的定義也不相同,下面是vc6.0中x86平台的定義

_intsizeof 巨集,獲取型別占用的空間長度, 增加的位元組數需保證為為int的整數倍,保證記憶體對齊(tp引數描述了當前引數的型別)。

#define _intsizeof(tp)   ( (sizeof(tp) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(p_list,arg)  ( p_list = (va_list)&arg + _intsizeof(arg) )
#define va_arg(p_list,tp)    ( *(tp *)((p_list += _intsizeof(tp)) - _intsizeof(tp)) )
va_end巨集,清空va_list可變引數列表:

#define va_end(p_list)      ( p_list = (va_list)0 )
我們來看乙個實際的例子

#include

#include

//可變引數

void

fun1

(int len,..

.)//注意,一定要獲取可變引數的長度

va_end

(v_arg)

;return;}

intmain()

----out----;

123

了解了可變引數的實現原理,我們可以自己嘗試,使用指標陣列構造乙個可變引數列表。

#define v_l(p_v,tp) *(tp*)*(p_v+v_l_i++)

int v_l_i =0;

void

fun1

(int len,

int*

*p_vlist)

intmain()

;fun1(3

,p_vlist)

;return0;

}----out--

--1.100000

2c

如何解析 * (char* )*(p_vlist+2);

*

(char*)

*(p_vlist+2)

;/*p_vlist+2,指標陣列的第二個指標成員的位址

*(p_vlist+2),獲取該位址儲存的指標變數值

(char* )*(p_vlist+2),強制轉換為char型別的指標

* (char* )*(p_vlist+2),從該位址提取char變數

*/

實際上,編譯器對va_list可變引數的函式的原型檢查不夠嚴格,對程式設計查錯不利.不利於我們寫出高質量的**。 想要實現可變引數,我們應該利用c++多型性或者 initializer_list標準庫 來實現可變引數的功能 。

C語言可變引數實現

第一 什麼是可變引數 int printf const char format,看到printf的定義大家就知道了,只有乙個固定的const char 引數,後面的都是不定長的引數列表了。第二 自己寫乙個可變引數函式 1.引數形參方式,跟printf類似,第乙個為固定引數,後面的用.代替 2.包含s...

C語言可變引數函式怎麼寫?

這裡的可變引數指的是引數的個數和型別不確定,比如我們熟悉的printf,原型是int printf const char format,那麼我們自己怎麼實現呢?比如我寫個函式名叫foo,參考printf寫成如下格式,void foo const char fmt,然後我們需要使用stdarg.h這個...

c語言可變引數實現示例

這段 展示了如何不使用中的va list va start va end巨集來實現自定www.cppcns.com義可變引數以及如何改變預設的 d f s等格式字元。複製 如下 include include itoa and ltoa include strcat and strlen echo ...