//输出结果* S* `, {' A8 ~
参数 #0 是: This D' w, ]' P( u7 m' j/ F
参数 #1 是: is7 _* L( c' \, T/ t& r
参数 #2 是: a+ p8 ~8 |" \- S- c% a& j. w. R# R3 Q' y3 o
参数 #3 是: demo!
- m2 @8 A, ~' L. s 注意到上面的例子没有使用第一个参数,下面的例子将使用所有参数3 \* X) I$ |& u! C, C) X9 s1 y
//================================ 例子程序2 ===============2 R6 a" k* |$ b# g x
#i nclude+ @# N: o3 a5 _
#i nclude
9 R( Q2 t( w: i. w8 g" U7 q int average( int first, ... ); //输入若干整数,求它们的平均值
9 X$ I$ D3 f; G8 z$ J void main( void )
9 B, [* O0 R7 Y {
/ x+ G6 L7 x. T. ]$ Y /* 调用3个整数(-1表示结尾) */
7 T, l; Q8 j; w7 k& }$ q printf( "Average is: %d\n", average(2,3,4, -1));& z5 `6 {5 m4 }% y" W3 y4 y
/*调用4个整数*/! Q& r+ `' G+ Y. k8 d @
printf( "Average is: %d\n", average(5,7,9, 11,-1));2 l6 s# _0 N7 v* E8 X& Y
/*只有结束符的调用*/" H; ?0 _3 T3 b# k: e
printf( "Average is: %d\n", average(-1) );4 w1 }. g7 d' W8 \
}
- ~* r( M. L1 s- m1 ]( ~2 R /* 返回若干整数平均值的函数 */
4 d: a' G6 n* {& Z5 F9 n7 X int average( int first, ... )
; T% h. e. U6 x9 B {
2 [6 D8 T+ O& |, [- Z. n, P int count = 0, sum = 0, i = first;% ^( d+ k0 f- d* ?- H
va_list marker;8 @; O0 f0 S/ n3 {4 z
va_start( marker, first ); //初始化
) |2 s( m& x! N* m+ x while( i != -1 )3 L& X9 B2 Q0 u
{; p+ M6 C: z$ H4 h* m6 u
sum += i; //先加第一个参数$ ?5 q% R6 S/ X P1 s3 a5 J
count++;: i6 C! ^0 w5 C2 N. I3 Z: ?4 z
i = va_arg( marker, int);//取下一个参数$ }# R" |2 G5 w5 i3 j
}
4 O& E6 m1 b1 q% f* _' W1 ] va_end( marker );
' |( e$ k+ ]" H6 A" K( @9 J' E return( sum (sum / count) : 0 );+ X) y+ |( U4 v
}
. X6 P% M1 J, x* [4 O: F3 Y //输出结果
; g% d2 P! W P$ L+ l Average is: 3: x1 z* K# A& t" w3 R" T
Average is: 8) ?; P% A+ n2 Q% z* p
Average is: 0: \ c! o2 k" x* w3 S# b
五、关于可变参数的传递问题0 @0 x. J; v, }) z, S% K
有人问到这个问题,假如我定义了一个可变参数函数,在这个函数内部又要调用其它可变参数函数,那么如何传递参数呢?上面的例子都是使用宏va_arg逐个把参数提取出来使用,能否不提取,直接把它们传递给另外的函数呢?
6 J9 i4 {. u: S. Z& a3 ^. _# W 我们先看printf的实现:
* n" C n2 e: c# E! R int __cdecl printf (const char *format, ...)$ M2 C* _0 S# S
{. K% C/ l( r* K; J3 m) H
va_list arglist;
" ~/ _; G/ ^5 a$ X* P: P, U int buffing;7 y% q: n8 \. { w1 D, h4 V* m
int retval;/ E1 J9 J: H+ w6 h9 @+ C
va_start(arglist, format); //arglist指向format后面的第一个参数, B" S7 `% I! r
...//不关心其它代码5 g) f% q) J4 F- |1 o* l
retval = _output(stdout,format,arglist); //把format格式和参数传递给output函数+ O. i7 k( W+ X0 G" M6 Q
...//不关心其它代码6 W1 ~6 A* Y- d, r5 n$ F8 @
return(retval);+ R7 G. ~" k& ?* W# c
}
3 c4 V" j3 I+ m* _* Z 我们先模仿这个函数写一个:
3 u$ w/ L$ ^6 P9 n4 S K #i nclude# ^/ w8 c5 d9 p6 m6 p7 [7 G
#i nclude
' ^ d* R) M; Y! e* f$ T int mywrite(char *fmt, ...)
0 N5 Z @: G7 L d* z: m( X {+ d& I' N- D- }' _6 Q
va_list arglist;
; S, M! V5 N/ N5 @# C va_start(arglist, fmt);
/ g: B+ x; J9 w2 G+ z* U return printf(fmt,arglist);
: ]4 T$ y7 O0 ]( R r }- L' E3 z: p! d! Y8 @& b; u% a2 ~
void main()3 {3 F: P1 [+ n
{, Q" Q2 s3 _( K1 R% P
int i=10, j=20;
" G/ |& p/ @* T c* k. [! {! s+ c char buf[] = "This is a test";2 Z( `& V: a" E2 H3 V1 W* v
double f= 12.345;( ?/ d7 w/ i. f% i3 M
mywrite( "String: %s\nInt: %d, %d\nFloat :%4.2f\n", buf, i, j, f);
$ }8 H1 B) S( k' l2 t: d) l* p } |