我是看了msdn后,感覺還是很簡單的,只要知道三個東西
va_arg, va_start, va_end
va_arg:
typeva_arg(
?? va_listarg_ptr,
?? type
);

va_arg returns the current argument; va_start and va_end do not return values

The va_arg, va_end, and va_start macros provide a portable way to access the arguments to a function when the function takes a variable number of arguments. Two versions of the macros are available: The macros defined in STDARG.H conform to the ANSI C standard, and the macros defined in VARARGS.H are compatible with the UNIX System V definition. The macros are:

The ANSI C standard macros, defined in STDARG.H, are used as follows:

  • All required arguments to the function are declared as parameters in the usual way. va_dcl is not used with the STDARG.H macros.
  • va_start sets arg_ptr to the first optional argument in the list of arguments passed to the function. The argument arg_ptr must have va_list type. The argument prev_param is the name of the required parameter immediately preceding the first optional argument in the argument list. If prev_param is declared with the register storage class, the macro's behavior is undefined. va_start must be used before va_arg is used for the first time.
  • va_arg retrieves a value of type from the location given by arg_ptr and increments arg_ptr to point to the next argument in the list, using the size of type to determine where the next argument starts. va_arg can be used any number of times within the function to retrieve arguments from the list.

The example:

//?crt_va.c
/*?The?program?below?illustrates?passing?a?variable
?*?number?of?arguments?using?the?following?macros:
?*??????va_start????????????va_arg??????????????va_end
?*??????va_list?????????????va_dcl?(UNIX?only)
?
*/


#include?
<stdio.h>
#define?ANSI????????????/*?Comment?out?for?UNIX?version?????*/
#ifdef?ANSI?????????????
/*?ANSI?compatible?version??????????*/
#include?
<stdarg.h>
int?average(?int?first,??);
#else???????????????????/*?UNIX?compatible?version??????????*/
#include?
<varargs.h>
int?average(?va_list?);
#endif

int?main(?void?)
{
???
/*?Call?with?3?integers?(-1?is?used?as?terminator).?*/
???printf(?
"Average?is:?%d\n",?average(?2,?3,?4,?-1?)?);

???
/*?Call?with?4?integers.?*/
???printf(?
"Average?is:?%d\n",?average(?5,?7,?9,?11,?-1?)?);

???
/*?Call?with?just?-1?terminator.?*/
???printf(?
"Average?is:?%d\n",?average(?-1?)?);
}


/*?Returns?the?average?of?a?variable?list?of?integers.?*/
#ifdef?ANSI?????????????
/*?ANSI?compatible?version????*/
int?average(?int?first,??)
{
???
int?count?=?0,?sum?=?0,?i?=?first;
???va_list?marker;

???va_start(?marker,?first?);?????
/*?Initialize?variable?arguments.?*/
???
while(?i?!=?-1?)
???
{
??????sum?
+=?i;
??????count
++;
??????i?
=?va_arg(?marker,?int);
???}

???va_end(?marker?);??????????????
/*?Reset?variable?arguments.??????*/
???
return(?sum???(sum?/?count)?:?0?);
}

#else???????/*?UNIX?compatible?version?must?use?old-style?definition.??*/
int?average(?va_alist?)
va_dcl
{
???
int?i,?count,?sum;
???va_list?marker;

???va_start(?marker?);????????????
/*?Initialize?variable?arguments.?*/
???
for(?sum?=?count?=?0;?(i?=?va_arg(?marker,?int))?!=?-1;?count++?)
??????sum?
+=?i;
???va_end(?marker?);??????????????
/*?Reset?variable?arguments.??????*/
???
return(?sum???(sum?/?count)?:?0?);
}

#endif


最主要的是average 函數
開始時申明一個va_list marker
后來調用va_start(marker);
再后來調用va_arg(marker, int)
最后結束時調用va_end(marker):