1 #include <stdio.h> 2 #include <stdarg.h> 3 4 void WriteFormatted (FILE * stream, const char * format, ...) 5 { 6 va_list args; 7 va_start (args, format); 8 vfprintf (stream, format, args); 9 va_end (args);10 }11 12 int main ()13 {14 FILE * pFile;15 16 pFile = fopen ("myfile.txt","w");17 18 WriteFormatted (pFile,"Call with %d variable argument.\n",1);19 WriteFormatted (pFile,"Call with %d variable %s.\n",2,"arguments");20 21 fclose (pFile);22 getchar();23 return 0;24 }
The implementation principle of va_list is as follows:
In the process, stack addresses are allocated from high to low. when a function is executed, the parameter list is pushed into the stack, the high address of the stack, the return address of the function, and the Execution Code of the function, the stack address is constantly decreasing during the stack import process.
In short, the distribution of functions in the stack is: address from high to low, in turn: function parameter list, function return address, function Execution Code segment. in the stack, the distribution of each function is in reverse order. that is, the highest part of the last parameter in the list, and the first parameter in the lowest part of the list address.
The functions used above are actually macros. They are used to obtain the address of the function parameter list. Their definitions are as follows:
1 # DEFINE _ intsizeof (N) (sizeof (n) + sizeof (INT)-1 )&~ (Sizeof (INT)-1) 2 # define va_start (AP, V) (AP = (va_list) & V + _ intsizeof (v )) // The first optional parameter address 3 # define va_arg (AP, t) (* (T *) (AP + = _ intsizeof (t )) -_ intsizeof (t) // The next parameter address 4 # define va_end (AP) (AP = (va_list) 0) // set the pointer to invalid