Function with Variable Parameter count in C Language
When using C language programming, the number of formal parameters in the function is usually determined, and all the actual parameters corresponding to the formal parameters should be given in sequence during the call. However, in some cases, the number of parameters of the function can be determined as needed. Typical examples include the functions printf (), scanf (), and execl () called by the system. So how are they implemented? The C compiler usually provides a series of macros to handle this situation to shield the differences caused by different hardware platforms and increase program portability. These macros include va_start, va_arg, and va_end.
There are two different forms of using these macros. The two have different header files in the program, and there are some differences in macro definitions.
When the ANSI standard form is used, the prototype declaration of a function with a variable number of parameters is:
Type funcname (type para1, type para2 ,...)
This form requires at least one common form parameter, and the ellipsis behind it does not mean to be omitted, but is part of the function prototype. Type is the type of function return values and formal parameters.
When the Declaration method is compatible with UNIX System V, the prototype of a function with a variable number of parameters is:
Type funcname (va_alist)
Va_dcl
This form does not require any common form parameters. Type is the type of the function return value. Va_dcl is a detailed declaration of the parameter va_alist in the function prototype declaration. It is actually a macro definition. Different types are used for different hardware platforms, but a semicolon is included at the end. Therefore, you do not need to add a semicolon after va_dcl. Va_dcl must be provided in the Code as is. Va_alist can be provided as is or omitted in VC, but it should be omitted in the CC or GCC on UNIX.
In addition, use the header file stdarg. the program written by H complies with the ANSI standard and can run on various operating systems and hardware. The header file varargs is used. H is only used for compatibility with previous programs. Therefore, we recommend that you use the former. The following describes how to process parameters in the previous method. The basic principles of the two methods are the same, but there are some minor differences in syntax form.
Va_start points argp to the first optional parameter. Va_arg returns the current parameter in the parameter list and points argp to the next parameter in the parameter list. Va_end clears the argp pointer to null. The function can traverse these parameters multiple times, but all parameters must start with va_start and end with va_end.
When a caller calls a function with a variable number of parameters, the caller must specify the number of actual parameters in a certain way. For example, the last parameter is set to a null string (execl () is called by the system () this is the case),-1, or other methods (the printf () function determines the number of actual parameters through the first parameter, that is, the definition of the output format ).
The following is a specific example. The first part is the code that complies with ANSI standards, and the last part is the code that is compatible with UNIX System V. Some comments are added to the code, so I will not explain them here. This example has been compiled and run properly in VC/Windows NT4.0, CC/aix4.3.2.0, and GCC/RedHat Linux 6.0 environments.
1. demonstrate how to use functions with variable parameter numbers in the ANSI standard format
# Include <stdio. h>
# Include <string. h>
# Include <stdarg. h>
/* The function prototype Declaration requires at least one definite parameter,
Note the ellipsis in brackets */
Int demo (char *,...);
Void main (void)
{
Demo ("Demo", "this", "is", "A", "Demo! "," \ 0 ");
}
/* ANSI standard declaration method. The ellipsis in parentheses indicates an optional parameter */
Int demo (char * MSG ,...)
{
Va_list argp;/* define the structure for saving function parameters */
Int argno = 0;/* Number of record parameters */
Char * para;/* stores the retrieved string parameters */
/* Argp points to the first input optional parameter,
MSG is the final parameter */
Va_start (argp, MSG );
While (1 ){
Para = va_arg (argp, char *);/*
Retrieve the current parameter, type: char *.*/
If (strcmp (para, "\ 0") = 0)
/* Use an empty string to indicate the end of the parameter input */
Break;
Printf ("parameter # % d is: % s \ n", argno, para );
Argno ++;
}
Va_end (argp);/* Set argp to null */
Return 0;
}
2. demonstrate how to use functions with variable parameter numbers in a way compatible with UNIX System V
# Include <stdio. h>
# Include <string. h>
# Include <varargs. h>
/* Function prototype declaration. The type va_list in parentheses is
VC/Windows NT4.0 can be retained,
But it needs to be removed in Aix and Linux, that is, changed to int demo ()*/
Int demo (va_list );
Void main (void)
{
Demo ("this", "is", "A", "Demo! "," \ 0 ");
}
/* The declaration method adopted by UNIX System V, which is enclosed in brackets
Va_alist, not va_list, and
The end of va_dcl does not require a semicolon */
Int demo (va_alist)
Va_dcl
{
Va_list argp;
/* Define the structure for saving function parameters */
Int argno = 0;
/* Record parameter count */
Char * para;
/* Store the extracted string parameters */
Va_start (argp );
/* Argp points to the first optional parameter */
While (1 ){
Para = va_arg (argp, char *);
/* Retrieve the current parameter, type: Char **/
If (strcmp (para, "\ 0") = 0)
/* Use an empty string to indicate the end of the parameter input */
Break;
Printf ("parameter # % d is: % s \ n", argno, para );
Argno ++;
}
Va_end (argp );
/* Set argp to null */
Return 0;
}
Http://www.cnblogs.com/dongzhiquan/archive/2010/01/07/1994678.html