摘要
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 ...