C functions use the following Macros in the program:
Void va_start (va_list arg_ptr, prev_param );
Type va_arg (va_list arg_ptr, type );
Void va_end (va_list arg_ptr );
Va_list: A type used to save the information required by macros va_start, va_arg, and va_end. To access parameters in the variable-length parameter list, you must declare
Definition of an object of the va_list type: typedef char * va_list;
Va_start: the macro used to access the parameter in the variable length parameter list. It initializes the object declared with va_list, and the initialization result is used by the macro va_arg and
Use va_end;
Va_arg: expands into a macro of an expression that has the value and type of the next parameter in the variable-length parameter list. Each call to va_arg will be modified
Object declared with va_list so that the object points to the next parameter in the parameter list;
Va_end: This macro enables the program to normally return data from the function referenced by the macro va_start in the variable length parameter list.
Va here is the meaning of Variable-argument (Variable Parameter.
These macros are defined in stdarg. h, so the program that uses variable parameters should contain this header file. next we will write a simple variable parameter function. The function should have at least one integer parameter, and the second parameter is also an integer, which is optional. the function only prints the values of these two parameters.
# Include <stdio. h >;< br/>#include <string. h >;< br/>#include <stdarg. h >;</P> <p>/* ANSI standard declaration method, the ellipsis in parentheses indicates the optional parameter */</P> <p> int demo (char * MSG ,...) <br/>{< br/> va_list argp;/* defines the structure of the stored function parameters */<br/> int argno = 0; /* record parameter count */<br/> char * para; /* store the retrieved string parameters */</P> <p>/* argp points to the first input optional parameter, MSG is the final parameter */<br/> va_start (argp, MSG); </P> <p> while (1) <br/>{< br/> para = va_arg (argp, char *);/* retrieves the current parameter, The type is char *. */<br/> If (strcmp (para, "/0") = 0) <br/>/* use an empty string to indicate that the parameter is input. */<br/> break; <br/> printf ("parameter # % d is: % s/n ", argno, para); <br/> argno ++; <br/>}< br/> va_end (argp ); /* Set argp to null */<br/> return 0; <br/>}</P> <p> void main (void) <br/>{< br/> demo ("Demo", "this", "is", "A", "Demo! "," 333333 ","/0 "); </P> <p>}
From the implementation of this function, we can see that the following steps should be taken to use variable parameters:
1) first define a va_list variable in the function. Here is arg_ptr. This variable
Volume is a pointer to a parameter.
2) then use the va_start macro to initialize the variable arg_ptr. The second parameter of this macro is
The previous parameter of a variable parameter is a fixed parameter.
3) then return the variable parameter with va_arg and assign the value to the second integer J. va_arg.
The parameter is the type of the parameter you want to return. Here it is the int type.
4) use the va_end macro to end variable parameter acquisition. Then you can make
The second parameter is used. If the function has multiple variable parameters, call va_arg to obtain
Take parameters.
Ii. Variable Parameter type traps
The following code is incorrect and unexpected results are not displayed during the running:
View plaincopy to clipboardprint?
Va_start (parg, plotno );
Fvalue = va_arg (parg, float); // The type should be changed to double. Float is not supported.
Va_end (parg );
Va_start (parg, plotno );
Fvalue = va_arg (parg, float); // The type should be changed to double. Float is not supported.
Va_end (parg );
The following lists types not supported by the va_arg (argp, type) macro:
-- Char, signed Char, and unsigned char
-- Short, unsigned short
-- Signed short, short int, signed short int, unsigned short int
-- Float
In C language, when a function without a prototype declaration is called, the caller will execute "Default argument promotions" for each parameter )". This rule also applies to variable parameter functions. For each actual parameter after the variable length parameter list exceeds the form parameter of the last type declaration, the above upgrade is also performed.
The improvement is as follows:
-- The actual parameter of float type will be upgraded to double
-- The actual parameters of char, short, and corresponding signed and unsigned types are upgraded to int
-- If int cannot store the original value, it is upgraded to unsigned Int.
Then, the caller passes the upgraded parameter to the caller.
Therefore, the Variable Parameter Function cannot receive the actual parameters of the above type.
C/C ++ has the following descriptions:
This trap is not mentioned in the C language programming chapter on the variable length parameter list. But there are rules for improving the default actual parameters:
In the absence of a function prototype, both the char and short types will be converted to the int type, and the float type will be converted to the double type.
-- C language programming version 2nd type conversion p36
This rule is also mentioned in other books:
It is clear that if a parameter is not declared, the compiler will have no information to perform standard type checks and conversions on it.
In this case, a char or short will be passed as an int, and float will be passed as a double.
These operations may not be expected by programmers.
Note: These are standard improvements inherited by C.
For parameters represented by ellipsis, the actual parameters always perform these enhancements before being passed (if they belong to the type to be upgraded), and the upgraded values are passed to the relevant functions. -- Translator's note
-- C ++ programming language version 3rd-Special Edition 7.6 P138
...... Float parameters are automatically converted to the double type. Parameters of the short or char type are automatically converted to the int type ......
-- C traps and defects: 4.4 form parameters and values of real participation in P73
There is a trap to avoid:
The 2nd parameters of the va_arg macro cannot be specified as char, short, or float.
Because char and short parameters are converted to the int type, float parameters are converted to the double type ......
For example, this is definitely not correct:
C = va_arg (AP, char );
Because we cannot pass a char parameter, if it is passed, it will be automatically converted to the int type. The above formula should be written:
C = va_arg (AP, INT );
-- C traps and defects p164