variable-length argument lists

来源:互联网 发布:react php 编辑:程序博客网 时间:2024/06/05 15:16

The best example of variable-length argument lists function is printf()

the proper declaration for printf() is 

                                                             int printf(char * format,...)

where the declaration ... means that the number and types of these arguments may vary.the declaration ... can only appear at the end of an argument list, ourmainprintfis declared as

                      int minprintf(char * fmt,...)

since we will not return the character count the the printf does.

      the tricky bit is how  minprintf  walks along the argument list when the list doesn't even have a name. the standard header<stdarg.h> contains a set of macro definitions that define how to step through an argument list.the implementation of this header will vary from machine to machine,but the interface it presents is uniform.

      the type va_list is used to declare a variable that will refer to each argument in turn; in minprintf ,this variable is call ap.for "argument pointer" the macro va_start initialize ap to point to the first unnamed argument.it must be called once beforeapis used.there must be at least one named argument;the final argument is used by va_start to get started.each call ofva_argreturns one argument and steps ap to the next; va_arg uses a type name to determine what type to return and how big a step to take.finally ,va_end does whatever cleanup is necessary.it must be called before the function returns.

    the properties form the basis of our simplified printf:

     

[code=C/C++]#include<stdarg.h>void minprintf(char * fmt,...) {     va_list ap; char * p,*sval;    int ival; double dval;     va_start(ap,fmt);//make ap point to first unnamed arg    for(p=fmt;*p;p++)     { if(*p != '%')  { putchar(*p); continue; } switch(*++p)  { case 'd': ival = va_arg(ap,int); printf("%d",ival); break; case 'f':  dval = va_arg(ap,double); printf("%f",dval);  break; case 's': for(sval = va_arg(ap,char *);*sval;sval++) { putchar(*sval); } break;  default:  putchar(*p);  break;  }     }    va_end(ap);//clean up when done }[/code]