Overview C language has a length uncertain parameter, such as "...", which is mainly used in a function of the number of parameters, and our most easily think of the example is the Printf function. Prototype:
INT Printf (const char * format [, argument] ...); use case:
Printf ("Enjoy YourSelf Everyday! / N); Printf (" The Value IS% D! / N "; Value); This variable parameter can be said to be a C language a more difficult part, here will be The problem triggered some analysis of it. Note: There is a function overload in C can be used to distinguish between different function parameters, but it still does not represent any number of function parameters. Question: Printf implementation, how to implement the Printf function, how to deal with the variable parameter problem? Answer and Analysis: Define a header file
Typedef char * va_list; #define va_start (list) list = (char *) & VA_ALIST # define v_end (list) #define va_arg (list, mode) / ((Mode *) (List = sizeof (Mode)) [ 1] Implement Printf: #include
INT Main (int Argc, char * argv []); the parameters of the function are Argc and Argv. Think in depth, "can only determine the parameters in runtime", that is, you can't see the parameters accepted from the statement, that is, the parameters are not fixed in the form. Common ways is that you can use it to point to the actual parameter area by defining a VOID * type, and then explain their meaning as needed in the function. This is the meaning of Argv in the main function, and ARGC is used to indicate the number of actual parameters, which provides us with further convenience, of course, this parameter is not required. Although the parameters do not have a fixed form, we will inevitably analyze the meaning of parameters in the function, so there will be a requirement, which is the format, size, validity of the caller and the subject, etc. Danching, otherwise, all the words were miserable. Question: The conversion of the variable length parameters is sometimes necessary to write a function, pass it directly to another function. Can this require? Answer and analysis: Currently, you have no way to do this directly, but we can go backwards, first, we define the parameters of the called function as the VA_List type, and convert the variable length parameter list to VA_LIST in the call function. This allows the conversion of the long parameter. See below: Void Subfunc (char * fmt, va_list argp) {... arg = va_arg (fmt, argp); / * Remove the necessary parameters from Argp * / ...} void mainfunc (char * fmt) , ...) {va_list argp; va_start (argp, fmt); / * converts the variable length parameters to VA_LIST * / SUBFUNC (FMT, Argp); / * Pass VA_LIST to sub-function * / va_end (argp); ...} Problem: The type of variable length parameter is a function pointer I want to use VA_ARG to extract the parameters of the type of variable length parameter to function pointer, but it is always incorrect, why? Answer and analysis: This is related to the implementation of VA_ARG. A simple, the demonstration version of the VA_ARG implementation is as follows:
#define va_arg (argp, type) / (* ((aRGP) = sizeof (type)) - SIZEOF (TYPE))) where the type of Argp is char *. If you want to extract the parameters of the function pointer type from the variable parameter list, for example
INT (*), then VA_ARG (argp, int (*)) is expanded to: (* (int (*) () *) ((argp) = sizeof (int (*)) ) -sizeof (int (*))))))))))) Obviously, (int (*) () *) is meaningless. The way to solve this problem is to define the function pointer to define a separate data type, for example:
Typedef int (* funcptr) (); then call VA_ARG (Argp, Funcptr again) to be expanded to:
(* (Funcptr *) ((argp) = sizeof (funcptr)) - SIZEOF (FUNCPTR)) This can be compiled. Problem: The acquisition of the variable length parameters has such a function with variable length parameters, where the following code is used to obtain the type of FLOAT: VA_ARG (Argp, Float); Do you do this? Answer and analysis: No. In variable length parameters, the application is "widened" principle. That is, the float type is expanded into Double; char, SHORT is extended into int. Therefore, if you want to go to the variable length parameter list, you need to use Va_arg (Argp, Double). Use VA_ARG (Argp, int) to the char and short types. Problem: Defining a limit for variable length parameters Why is my compiler not allowed me to define the following functions, that is, the variable length parameters, but there is no fixed parameter?
INT f (...) {...} Answer and Analysis: No. This is requested by ANSI C, you can define a fixed parameter at least. This parameter will be passed to VA_START (), and then use VA_ARG () and VA_END () to determine the type and value of the variable length parameters when the actual call is actually invoked.