在C语言中比较常用的可变参数就是printf();函数原型如下:5 T7 H: a, E4 T5 q9 {* _: J
int printf(const char * format,...);/ I+ k- Z9 w' }5 T! O7 C; M
写一个简单的可变参数:
K# F! F1 { t: S #include
2 g6 k! Q! p9 Y( ?5 H void va_fun(int i,...);
4 k; x- U8 H: d. y8 l) ~" Q int main(void): k# ~* I, X. o# l
{
. N% Y% H7 }& m; W va_fun(100);; K$ r% }/ e- O9 T, L8 | N
va_fun(200,100);4 ^5 H3 s+ Z! Q: p% V& I6 F$ Z; I
va_fun(100,200,300);
- H% Y/ l6 O& D7 z1 z" ~ }
! u. D' c/ V4 a7 d$ Q/ [ V void va_fun(int i,...)
+ y2 c( ~3 E9 r) d# M* Q {
* m' p- R+ J4 I- P* p& j: h% Q- K va_list arg_ptr;% K: P8 T# z/ z) D- T
int j = 0;7 O$ t8 W! v0 q* C# I
va_start(arg_ptr,i);
: ^0 |, `: c F3 o1 O5 i8 p8 x j = va_arg(arg_ptr,int);0 {, [3 S+ ^ p8 S5 w: A9 ~* U
va_end(arg_ptr);
1 U1 y6 t p6 \& `0 Z& o1 B printf("%d %d\n",i,j);
7 ?. P. v5 E2 j4 L- N& _. `- J }
8 o! q( q: j3 N2 T, P 这样就实现了一个简单的可变参数。其实可变参数是利用宏来实现的,宏在参数的堆栈中查找参数的位置,然后返回。% _( c7 B' z( n6 j- A
定义如下:
" A, `- P- l0 Z typedef char * va_list;- w( E9 W$ Q+ z1 E6 b; p* F
#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
$ t2 i( m! p/ G. x5 c8 A% o #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ); j' H; w. s8 |: B% u
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )% y( i/ g8 x }! A/ p$ R
#define va_end(ap) ( ap = (va_list)0 )+ @' N- U" e* q9 r- r
其实就是计算参数堆栈中的内存地址。
3 K2 e) ^8 X: m- q; b0 ` 建议少用可变参数,在c++中用多态实现就可以。
! o0 f1 a( ?. z3 P# {) a printf中根据format中的参数的个数确定后面参数的个数。 |