The correct declaration form for the function printf is:
int printf (char *fmt, ...);
Where ellipses indicate that the number and type of parameters in the parameter table are variable (ellipses can only appear at the end of the parameter table). A similar parameter table is called the edge length parameter table. In addition to having a parameter fmt fixed, the number and type of parameters followed are variable (with three dots "..." to make the parameter placeholder).
In C programming language, Ritchie provides a simple version of the printf function minprintf:
#include <stdarg.h>void minprintf (char *fmt, ..) The { va_list ap; /* points to each unnamed parameter in turn */ char *p, *sval; int ival; double dval; va_start (AP,&NBSP;FMT); /* points the AP to the first unnamed parameter */ 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: &nbSp; putchar (*p); break; } } va_end (AP); /* at the end of cleanup work */}
The code is simple, and the key to writing a function minprintf is to handle a parameter table that doesn't even have a name. Below we start with the standard header file <stdarg.h>.
<stdarg.h> contains a set of macro definitions that define how the parameter table is traversed. The implementation of this header file differs depending on the machine, but the interface provided is consistent.
typedef char * VA_LIST; /* where VA represents variable argument variable parameter */#define _INTSIZEOF (N) (sizeof (n) + sizeof (int)-1) & ~ (sizeof (int)-1)) #define VA _start (ap,v) (AP = (va_list) &v + _intsizeof (v)) #define VA_ARG (Ap,t) (* (t *) (AP + = _intsizeof (t))-_intsize Of (T))) #define VA_END (AP) (AP = (va_list) 0)
Let's explain what these codes mean.
1. The va_list type is used to declare a variable that will refer to each parameter in turn. is defined as char*, because the character pointer type can be used to store memory cell addresses on the PC we are currently using. And on some machines va_list is defined as void*;
2, _intsizeof (n) I see a little puzzling, in fact, it is mainly for memory alignment, its principle can refer to the "_intsizeof (n) Resolution";
3, Va_start (AP, v), its parameter AP is va_list type, V for determining the parameter fmt. The function is to initialize the variable parameter list (the function is placed in the AP after the parameter address of the FMT);
4, Va_arg (AP, T) (T denotes the type of user input), (* (T *) ((AP + = _intsizeof (t))-_intsizeof (t))) This is not a careful look also can be confusing, AP how to First add _intsizeof (t) Is it not superfluous to subtract it? In fact, note the brackets, ap+= itself changed, and then the AP just participate in the expression calculation, AP will not change. So this macro does two things:
(1) using the type name entered by the user to cast the parameter address, to obtain the user's desired value;
(2) Calculate the actual size of this parameter, the pointer to the end of this parameter, that is, the first address of the next parameter for subsequent processing.
5, Va_end (AP), the x86 platform is defined as ap= (char*) 0; The AP no longer points to the stack, but is the same as null. Some are directly defined as ((void*) 0) so that the compiler does not generate code for Va_end, For example, GCC is defined in the Linux x86 platform.
Here are a few things to note: Because the address of the parameter is used for the Va_start macro, the parameter cannot be declared as a register variable or as a function or an array type. The description of Va_start, Va_arg, Va_end is these, we should note that different operating systems and hardware platform definitions are somewhat different, but the principle is similar.
Reference documents:
1, http://blog.chinaunix.net/uid-2413049-id-109789.html
2, "The C programming Language"
This article is from the "Yunfei Dance" blog, please make sure to keep this source http://wuyunncu.blog.51cto.com/5978596/1709929
Variable length parameter table