C ++ Variable Parameter Function writing explanation, function writing
Variable Parameter functions are written as follows:
Type Function (fixed parameter 1, fixed parameter 2 ,...... Fixed parameter n ,...);
It can be seen that there are two types of variable parameters: fixed parameters and variable parameters.
A fixed parameter is a parameter that must be input. The number and type of the parameter are determined. Common functions use fixed parameters.
Variable parameters use "…" . The number is not fixed.
A Variable Parameter Function must have at least one fixed parameter. Because variable parameters rely on the last fixed parameter to determine their first address.
Variable Parameter functions use the va function to support variable parameters.
The va function is defined inStdarg. hThey include: va_list, va_start (), va_arg (), va_copy (), and va_end ().
① Va_list: Variable Parameter List pointer. After va_start is called for initialization, the Pointer Points to The 0th element in the Variable Parameter List. The va_arg function is used to call the list element and move the pointer.
② Va_start (va_list object, the last fixed parameter): the initialization function of va_list. The two parameters are respectively the va_list object and the last fixed parameter. Use the last fixed parameter to initialize the va_list object.
For example
Void Test (int n0, doublen1, char n2 ,...)
{
Va_listarg_ptr;
Va_start (arg_ptr,N2);
......
}
The last fixed parameter is n2, so va_start (arg_ptr,N2); The second parameter is n2. This is irrelevant to the type of the last fixed parameter. The fixed parameter can be of any type.
③ Va_arg (va_list object, type): return the parameter indicated by the pointer in the parameter list. The return type is type, and move the pointer down to a position. Va_arg provides two functions: return the current parameter and point the pointer to the next parameter.
④ Va_copy (dest, src): the types of dest and src are va_list. va_copy () is used to copy the parameter list pointer and initialize dest as src.
⑤ Va_end (va_list object): clears the parameter list and sets the va_list object as invalid.
Va_start ()/va_copy ()... Va_end () is paired. All operations on the va_list object must be performed between the two.
If va_end () is called for clearing, a new va_list object can be created by calling va_start ()/va_copy.
Note: The va_list object cannot obtain the size, or you cannot obtain the number of parameters in the va_list object. In general, there are two methods to obtain the number of parameters in the va_list object: ① passing in parameters through the function ② adding a parameter at the end of the variable parameter, which is 0,-1 or a null string. In this way, you can judge within the function.
Example:
1. Passing parameters:
Int sum (int count,...) {va_list arg_ptr; va_start (arg_ptr, count); inttheSum = 0; for (int I = 0; I
2. Set the last uncertain parameter as the flag bit:
Int demo (char msg ,...) {va_list arg_ptr; char para; va_start (arg_ptr, msg); while (1) {para = va_arg (arg_ptr, char ); // each input variable parameter is of the char type if (strcmp (para, "") = 0) break; call para} va_end (arg_ptr); return 0 ;}
Call method: "demo (" DEMO "," This "," is "," a "," demo! "," ");", The last parameter indicates the end.
There is a limit for both of the preceding statements, that is, all input parameters of the same type are of the same type. Because va_arg (va_list object, type) needs to enter the type of the parameter currently pointed to. If multiple input parameters have different types, then va_arg (va_list object, type) the type parameter cannot be determined.
C uses a fixed parameter to pass in Char * pszFormat. In this string, % d/f/c explicitly specifies the order and type of the input parameters. In this way, as long as the fixed parameter is parsed within the function, the number of "%" is an indefinite number of parameters, and the variable type can be parsed by % characters in turn.
Example:
Void my_printf (const char * fmt ,...) {va_list ap; va_start (ap, fmt);/* use the last parameter of the parameter type to initialize the ap */for (; * fmt; ++ fmt) {/* if it is not a control character */if (* fmt! = '%') {Continue; // end a single loop}/* if it is a control character, view the next character */++ fmt; if ('\ 0' = * fmt)/* if it is the terminator */{assert (0);/* This is an error */break;} switch (* fmt) {case '%':/* two consecutive '%' output 1 '%' */putchar ('%'); break; case 'D ': /* output according to int */{/* The next parameter is int. Obtain */int I = va_arg (ap, int); printf ("% d", I );} break; case 'C':/* output by character */{/* The next parameter is char. * // The output cannot be char c = va_arg (ap, char ); int c = va_arg (ap, int); printf ("% c", c);} break;} va_end (ap);/* release ap */}
For 'C' parsing, int c = va_arg (ap, int) is used );
This is because in C language, when calling a function without a prototype declaration, the caller will execute "default actual parameter upgrade (default argumentpromotions)" for each parameter )".
At the same time, the above improvement is also performed for each actual parameter after the variable length parameter list exceeds the form parameter of the last type declaration.
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 unsignedint.
Then, the caller passes the upgraded parameter to the caller.
Similarly, if you need to use short and float, you should also do the following:
short s = (short)va_arg(ap,int);float f = (float)va_arg(ap,double);
In short, the type in va_arg (ap, type) cannot be of the following types:
-- Char, signedchar, and unsignedchar
-- Short, unsignedshort
-- Signedshort, signedshort, signedshint, and unsignedshint
-- Float