Variable parameters for C language

Source: Internet
Author: User

Variable parameters to the programming brought great convenience, in the enjoyment of its convenience, it is necessary to understand the implementation of the way, in the understanding of programming language, but also can extend the idea of programming.

Variable parameters need to use 3 macro functions and a type, they are defined in <stdarg.h>, respectively:

Va_start (VL)

Va_arg (VL, type)

Va_end (VL)

Where VL is the va_list type, type is the object type (such as int, double, or custom struct).

The Va_start function is used to initialize the VL

Va_arg (VL, type) is used to obtain the value of type variable, the macro will not be reversible to change the VL, so call Va_arg is to have order, can not mess, the specific order is the parameter order. The irreversible meaning is that it can only be called sequentially. You can, of course, call Va_start again, and then go through it sequentially.

Va_end is to make VL ineffective. Indicates that the parameter has been obtained

A simple example:

#include<stdio.h>voidVariableargumentmethod (intargc, ...); intMain () {Variableargumentmethod (6,4,7,3,0,7,9); return 0;} voidVariableargumentmethod (intargc, ...) {    //declares a pointer to hold a variable parameterva_list parg; //Initialize the PARG to point to the first argumentVa_start (PARG, ARGC); //Output Parameters     for(inti =0; I! = ARGC; ++i) {        //gets the parameter that the PARG points to and outputsprintf"%d,", Va_arg (PARG,int) ); } va_end (PARG);} 

The implementation of a mutable parameter is actually the address of the first parameter, and the type of the remaining parameters to determine their address. or know a base address (provided by the first parameter), and the offset of a parameter relative to the primary (provided by the parameter type), which is naturally the address of this parameter.

Therefore, there are two necessary conditions for a mutable function, 1. The first parameter must be provided explicitly so that the base address of the parameter in the stack is known. 2. All parameter types must be known. (The function of%D,%LF in the first parameter format of printf is to provide the parameter type to determine the parameter position)

Later, to understand these macros, you need to know exactly how to pass the arguments when the function is called, what the order of the arguments is, and the address alignment. See:

Http://www.cnblogs.com/cpoint/p/3368993.html

In short, the sequence of parameters in the stdcalll is from right to left into the stack, the bottom of the stack is high address, the top of the stack is low address, the growth direction of the stack is high to low. such as Func (Arg1, Arg2, Arg3), their addresses are: &arg1 < &ARG2 < &ARG3 and continuous.

(It's worth mentioning that when I look at fixed-parameter functions in GCC, such as func (Arg1, Arg2, Arg3), their addresses are &ARG1 > &arg2 > &arg3. Later look at the assembly only to know that the original compiler used a local variable to save parameters, printf printing is the address of local variables)

Here I only write some of my understanding of these macros.

First give the implementation details:

Char *  va_list;    #define _addressof (v)   (& (v))  #define _intsizeof (n)   (sizeof (n) + sizeof (int)-1) & Amp ~ (sizeof (int)-1))  #define va_start (AP,V)  (AP = (va_list) _addressof (v) + _intsizeof (v))  c13> #define va_arg (ap,t)    (* (t *) (AP + = _intsizeof (t))-_intsizeof (t))  #define

_intsizeof (n) indicates that the type of n is several times the int type (not an integer multiple of the rounding up). For example, a double is twice times the type int, and the char type is 1 time times the int, and a sizeof (struct my_struct) =10 is 3 times times the type of int. Why if int is an integer multiple, I'll say it later.

The Va_start (AP, V) AP is the va_list type, and V is the first parameter. Its purpose is to copy the AP as the starting address of the second parameter.

The Va_arg (AP, T) AP is of type va_list and T is the type of parameter you want to get. The function is to return the AP value first, and then set the AP to the starting address of the next parameter.

The Va_end (AP) is set to a null pointer.

where Va_start and Va_arg both call _intsizeof (n), _intsizeof (n) is the function of the macro to determine the actual amount of memory occupied by N (that is, address alignment is considered). Why does it have to be an integer multiple of int? By normal alignment rules, char can be as long as 1 bytes of space anyway. But when it comes to passing parameters,

There are exceptions, which are 4 bytes. This is because of the type promotion that occurs when the parameter is passed.

In the C language, when invoking a function without a prototype declaration, the caller performs a "default real-parameter promotion (argument promotions) for each parameter." The same rule applies to variadic functions--Each of the actual arguments after a variable-length parameter list exceeds the formal parameter of the last type declaration, will also perform the above promotion.

The lifting work is as follows:
The actual parameters of the--float type are promoted to double
The actual parameters of--char, short, and corresponding signed and unsigned types are promoted to int
--If int cannot store the original value, it is promoted to unsigned int

So the following code is wrong and the runtime does not get the expected result:

View Plaincopy to Clipboardprint?
Va_start (PARG, Plotno);
Fvalue = Va_arg (parg, float); Type should be changed to double, float not supported
Va_end (PARG);
Va_start (PARG, Plotno);
Fvalue = Va_arg (parg, float); Type should be changed to double, float not supported
Va_end (PARG);

After figuring out what _intsizeof means. Continue explaining Va_start (AP, V) It is the starting address that makes the AP the second parameter. (V provides the base address, and provides the memory space it occupies, and the second parameter immediately after the first parameter, it is natural to get the position of the second parameter)

Va_arg (AP, T) actually it is the same as the first macro principle. Just a little change, the base address AP has been obtained by Va_start, T represents the parameter type.

#define Va_arg (ap,t) (* (t *) (AP + = _intsizeof (t))-_intsizeof (t)))


It must have seemed a little strange at first. Will ap+_intsizeof (t) and minus _intsizeof (t) be the original value of the AP? Hehe, in fact, the key point is the + =, this macro actually has a side effect, the return value is indeed the original value has not changed, but the AP itself +_intsizeof (t) to the start address of the next parameter.

Va_end (AP) There's nothing to talk about. Oh

Finally, attach a simple version of printf:

#include <stdarg.h>voidminprintf (Char*FMT, ...)    {va_list ap; Char*p, *Sval; intival; DoubleDval;    Va_start (AP, FMT);  for(p = fmt; *p; p++) {        if(*p! ='%') {Putchar (*p); Continue; }        Switch(*++p) { Case 'D': Ival= Va_arg (AP,int); printf ("%d", ival);  Break;  Case 'F': Dval= Va_arg (AP,Double); printf ("%f", Dval);  Break;  Case 's':             for(Sval = Va_arg (AP,Char*); *sval; sval++) Putchar (*sval);  Break; default: Putchar (*p);  Break; }} va_end (AP);}

Reference Links:

Http://blog.chinaunix.net/uid-27666459-id-3772622.html

Http://www.cnblogs.com/cpoint/p/3368993.html

Http://www.cnblogs.com/Anker/archive/2012/12/27/2836495.html

Variable parameters for C language

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.