#include
type va_arg( va_list argptr, type );
void va_end( va_list argptr );
void va_start( va_list argptr, last_parm );
The va_arg() macros are used to pass a variable number of arguments to a function.
First, you must have a call to va_start() passing a valid va_list and the mandatory first argument of the function. This first argument can be anything; one way to use it is to have it be an integer describing the number of parameters being passed.
Next, you call va_arg() passing the va_list and the type of the argument to be returned. The return value of va_arg() is the current parameter.
Repeat calls to va_arg() for however many arguments you have.
Finally, a call to va_end() passing the va_list is necessary for proper cleanup.
For example:
int sum( int num, ... ) {
int answer = 0;
va_list argptr;
va_start( argptr, num );
for( ; num > 0; num-- ) {
answer += va_arg( argptr, int );
}
va_end( argptr );
return( answer );
}
int main( void ) {
int answer = sum( 4, 4, 3, 2, 1 );
printf( "The answer is %d\n", answer );
return( 0 );
}
This code displays 10, which is 4+3+2+1.
Here is another example of variable argument function, which is a simple printing function:
void my_printf( char *format, ... ) {
va_list argptr;
va_start( argptr, format );
while( *format != '\0' ) {
// string
if( *format == 's' ) {
char* s = va_arg( argptr, char * );
printf( "Printing a string: %s\n", s );
}
// character
else if( *format == 'c' ) {
char c = (char) va_arg( argptr, int );
printf( "Printing a character: %c\n", c );
break;
}
// integer
else if( *format == 'd' ) {
int d = va_arg( argptr, int );
printf( "Printing an integer: %d\n", d );
}
*format++;
}
va_end( argptr );
}
int main( void ) {
my_printf( "sdc", "This is a string", 29, 'X' );
return( 0 );
}
This code displays the following output when run:
Printing a string: This is a string
Printing an integer: 29
Printing a character: X
//一个实例
程序要求:
做一个LOG函数
log_printfbuf(char *fmt, ...)
打印出printf所相同的东西,然后再打印出多余的2个参数的buffer内容。
多余的参数第一个是buffer, 第二个是要打印的字节数目。
比如调用
char buf[256];
buf[0] = 0;
buf[1] = 0;
buf[2] = 1;
strcpy(buf+3, "ABCDSKKKKLKKKKASKK");
log_printfbuf("buffer at %p size %d:", buf, sizeof(buf), buf, 56);
会打印出
buffer at 08001000 size 256: {00}{00}{01}ABCASKKKLKKLWIKKKK....
这是根据一个实际需求而来的。可能有一点用途。
程序实现:
#include
#include
#include
void foo(char *fmt, ...);
void show_hex(char *s , int d);
void main()
{
char buf[256]={0};
buf[0] = 0;
buf[1] = 0;
buf[2] = 1;
strcpy(buf+3, "ABCDSKKKKKLLLLKKKASKK");
foo("buffer at %p size %d:", buf, sizeof(buf), buf, 56);
}
void foo(char *fmt, ...) {
va_list ap;
int d;
char c, *s;
va_start(ap, fmt);
while (*fmt)
{
if (*fmt =='%')
{
switch(*(++fmt)) {
case 's': /* string */
s = va_arg(ap, char *);
printf("%s", s);
break;
case 'p':
s = va_arg(ap, char *);
printf("%04X", (int)s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("%d", d);
break;
case 'c': /* char */
/* need a cast here since va_arg only
takes fully promoted types */
c = (char) va_arg(ap, int);
printf("%c", c);
break;
}
}
else
printf( "%c", *fmt);
fmt++;
}
s = va_arg(ap, char *);
d = va_arg(ap, int);
show_hex(s,d);
va_end(ap);
}
void show_hex(char *s , int d)
{
for (int i =0 ; i< d ; i++)
{
printf("{%02X} ", (unsigned char)*(s+i));
}
printf("\n");
}