(1) variable parameters in C LanguageThe function of variable parameters can be obtained from the C language printf. The prototype of the printf function is as follows:
int printf ( const char * format, ... );
By using the variable number parameter, the number of input parameters is variable. For example, printf needs to input multiple real parameters according to the format parameter. (2) The following function myprintf is a simple printf function for variable parameters in C language. It is incomplete but can be used to describe the variable parameters.
/** Author: guojun07 */# include
# Include
# Include
# Include
Void myprintf (char * format ,...) {va_list ap; int pos = 0; int int_val = 0; float f_val; char buf [64]; memset (buf, 0, 64 ); // get all the parameters and put them in the next list ap. va_start (ap, format); while (format [pos]! = '') {// Judge '%', indicating to obtain the next parameter if (format [pos] = '%') {pos ++; switch (format [pos]) {case 'D': case 'U': // obtain the next parameter int_val = va_arg (ap, int); sprintf (buf, % d, int_val); // write data to the standard output write (STDOUT_FILENO, buf, strlen (buf); memset (buf, 0, 64); pos ++; break; case 'F': // obtain the next parameter f_val = (float) va_arg (ap, double); sprintf (buf, % f, f_val) in the ap ); // write data to the standard output write (STDOUT_FILENO, buf, strlen (buf); memset (buf, 0, 64); pos ++; break; default: break ;}} else {write (STDOUT_FILENO, & (format [pos]), 1); pos ++ ;}}int main (void) {myprintf (this is a testing, I = % d, u = % u, f = % f,-1, 5, 0.2); return 0 ;}
The program data result is as follows:
guojun8@guojun8-desktop:~/test/valist$ ./mainthis is a testing, i = -1, u = 5, f = 0.200000
(3) The implementation below describes the implementation of variable length parameters in C language. Its implementation is related to a data structure (va_list) and three macros (va_start, va_end, va_arg, from the source code, we can see the following implementation files from the Linux kernel source code (include/acpi/platform/acenv. h)
#ifndef _VALIST#define _VALISTtypedef char *va_list;#endif /* _VALIST */ /** Storage alignment properties*/#define _AUPBND (sizeof (acpi_native_int) - 1)#define _ADNBND (sizeof (acpi_native_int) - 1) /** Variable argument list macro definitions*/#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd)))#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))#define va_end(ap) (void) 0#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
A) va_list
From the implementation, we can see that the va_list type is actually a pointer;
B) va_start
This macro places the content after the parameter T points to in the ap, where _ bnd (A, _ AUPBND) returns the size of A and is aligned with the number of digits of the system machine, because the address of the parameter in the stack must be aligned with the system length, acpi_native_int indicates the machine length;
C) va_end
This macro returns 0;
D) va_arg
This macro is used to obtain the current parameter to which the ap points and point the ap to the next parameter in the parameter list;