在C语言中比较常用的可变参数就是printf();函数原型如下:
$ [/ [3 V/ {+ H int printf(const char * format,...);
& O1 r$ X7 F5 e# m" `& R* [ 写一个简单的可变参数:2 U& v5 X2 g( c# s
#include
$ u# F4 m' z( m& Y void va_fun(int i,...);
% E5 L! _) N7 ]0 g `7 g int main(void)
+ r/ d5 n2 z& A8 [2 L. P/ e* E {1 v! C# `) T$ s* b3 R% F+ R
va_fun(100);
6 v, h2 k3 s0 C% F& z- t) Q0 B; W9 r va_fun(200,100);! e' m7 Q+ P* D, L5 z$ {7 T2 A. B; Q
va_fun(100,200,300);2 A. v0 k5 v( s: g. V4 ?* d
}4 I2 W* h4 s, e0 ^- T9 {* ~) L
void va_fun(int i,...)6 o' S) {* c: o: o
{# l1 \) {7 y+ l. ~0 s
va_list arg_ptr;
% x4 ^% U. y4 Y' H( Y* k% H" d int j = 0;
) L, E5 G6 B8 q' `- Q( R s+ F8 `' X; z va_start(arg_ptr,i);
- J. o" g" B$ v j = va_arg(arg_ptr,int);
3 d" M' K, o4 n! O3 l+ m va_end(arg_ptr);
/ D% H% G5 [ L; q$ f printf("%d %d\n",i,j);- n, a) Y: [) Z2 P% H* K0 M5 @
}8 i, I- t6 ?9 ^$ d6 S& V( X
这样就实现了一个简单的可变参数。其实可变参数是利用宏来实现的,宏在参数的堆栈中查找参数的位置,然后返回。
$ ~) h: |4 i& W$ c, V0 X 定义如下:
, l1 D9 O G c5 v, |# f typedef char * va_list;
% p0 y5 e" f; e S2 @ #define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
" ? b8 e: D- u1 q* z- l# i #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )8 I& P. N& [( a
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )! G) p, t& n- o0 o3 ~2 c- V b, H& q
#define va_end(ap) ( ap = (va_list)0 )% H2 j; w r( @* `8 y1 x
其实就是计算参数堆栈中的内存地址。8 d- M; ]$ r/ }) M
建议少用可变参数,在c++中用多态实现就可以。
/ Q, ~: ~. Z7 e9 N5 G6 z, H printf中根据format中的参数的个数确定后面参数的个数。 |