Variable parameters in C Language

Source: Internet
Author: User

Overview

There is an uncertain length parameter in C language, such :"... ", Which is mainly used in functions with uncertain number of parameters. The most common example is the printf function.

Prototype:

Int printf (const char * Format [, argument]...);

Example:

Printf ("Enjoy yourself everyday! \ N ");
Printf ("the value is % d! \ N ", value );

This variable parameter can be said to be a difficult part to understand in the C language. Here there are several problems that will lead to some analysis on it.

Note: In C ++, function overload can be used to differentiate calls of different function parameters, but it still cannot represent any number of function parameters.

Problem: Implementation of printf

How can I implement the printf function and solve the Variable Parameter Problem? Answer and analysis:

A header file <stdarg. h> is defined in the Standard C language to deal with the variable parameter list. It contains a set of macros and a va_list typedef declaration. A typical implementation is as follows:

Typedef char * va_list;
# Define va_start (list) List = (char *) & va_alist
# Define va_end (list)
# Define va_arg (list, mode )\
(Mode *) (List + = sizeof (mode) [-1]
Implement printf by yourself:
# Include <stdarg. h>
Int printf (char * format ,...)
{
Va_list AP;
Va_start (AP, format );
Int n = vprintf (format, AP );
Va_end (AP );
Return N;
}

Problem: parameters are determined only during running.

Is there a way to write a function. The specific form of this function parameter can be determined at runtime?

Answer and analysis:

Currently, there is no "regular" solution, but there is a single eccentric, because there is a function that has set an example for us in this regard, that is, main (), its prototype is:

Int main (INT argc, char * argv []);

The function parameters are argc and argv.

Think deeply, "You can only determine the parameter format at runtime", that is, you cannot see the accepted parameters from the Declaration, that is, the parameters do not have a fixed form at all. A common method is to define a void * type parameter, use it to point to the actual parameter area, and then explain the meaning of the parameters as needed in the function. This is the meaning of argv in the main function, and argc is used to indicate the actual number of parameters, which provides further convenience for our use. Of course, this parameter is not required.

Although the parameters do not have a fixed form, we must parse the meaning of the parameters in the function. Therefore, we naturally have a requirement that the format of the content in the parameter zone should be between the caller and the called, size, effectiveness, and other aspects to reach an agreement, otherwise it will be miserable to talk about each other.

Problem: Transmission of variable length parameters

Sometimes, you need to write a function and pass its variable length parameter directly to another function. Can this requirement be implemented?

Answer and analysis:

At present, you have no way to do this directly, but we can make a detour. First, we define the parameter of the called function as the va_list type, at the same time, the variable length parameter list is converted to va_list in the call function, so that variable length parameters can be passed. See the following:

Void subfunc (char * FMT, va_list argp)
{
...
Arg = va_arg (FMT, argp);/* obtain the desired parameters one by one from argp */
...
}

Void mainfunc (char * FMT ,...)
{
Va_list argp;
Va_start (argp, FMT);/* convert the variable length parameter to va_list */
Subfunc (FMT, argp);/* pass va_list to the subfunction */
Va_end (argp );
...
}

Problem: The variable length parameter type is a function pointer.

I want to use va_arg to extract the variable length parameter with the type of function pointer, but the result is always incorrect. Why?

Answer and analysis:

This is related to the implementation of va_arg. A simple and demo version of va_arg is implemented as follows:

# Define va_arg (argp, type )\
(* (Type *) (argp) + = sizeof (type)-sizeof (type )))

The argp type is char *.

If you want to use va_arg to extract parameters of the function pointer type from the variable parameter list, for example

INT (*) (), then va_arg (argp, INT (*) () is extended:
(* (INT (*) () *) (argp) + = sizeof (INT (*) ()-sizeof (INT (*)())))

Obviously, (INT (*) () *) is meaningless.

To solve this problem, define the function pointer as an independent data type using typedef, for example:

Typedef int (* funcptr )();

At this time, calling va_arg (argp, funcptr) will be extended:

(* (Funcptr *) (argp) + = sizeof (funcptr)-sizeof (funcptr )))

In this way, you can pass the compilation check.

Problem: Get variable length parameters

There is such a function with variable length parameters, including the followingCodeUsed to obtain the real parameters of Float Type:

Va_arg (argp, float );

Can this be done?

Answer and analysis:

No. In variable length parameters, the "widening" principle is applied. That is, the float type is extended to double; char and short are extended to int. Therefore, if you want to go to the variable length parameter list for the original float type parameters, you need to use va_arg (argp, double ). Va_arg (argp, INT) is used for char and short types ).

Problem: A restriction for defining variable length parameters

Why does my compiler not allow me to define the following functions, that is, variable length parameters, but there is no fixed parameter?

Int F (...)
{
...
}

Answer and analysis:

No. This is required by ansi c. You must define at least one fixed parameter.

This parameter will be passed to va_start (), and then the va_arg () and va_end () will be used to determine the type and value of the variable length parameter for all actual calls.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.