Use stdarg. h to implement variable length parameters

Source: Internet
Author: User

Now, we will first explain the following process:

◎ Usage:
Func (type para1, type para2, type para3 ,... )
{
/****** Step 1 ******/
Va_list AP;
Va_start (AP, para3); // be sure to "…" The previous parameter, and this parameter cannot make the reference type, because the reference type cannot obtain the address of the following parameter according to its address

/****** Step 2 ******/
// At this time, the AP points to the first variable parameter.
// Call va_arg to obtain the value

Type xx = va_arg (AP, type );

// The type must be the same, for example:
// Char * P = va_arg (AP, char *);
// Int I = va_arg (AP, INT );

// If multiple parameters continue to call va_arg

/****** Step 3 ******/
Va_end (AP); // for robust!
}
Then I wrote a small program and you will understand the usage of stdarg. h.

 

# Include <iostream> # include <stdarg. h> const int n = 5; using namespace STD; void stdarg (INT A1 ,...) {Va_list argp; int I; int ary [N]; va_start (argp, A1); Ary [0] = A1; for (I = 1; I <N; I ++) ary [I] = va_arg (argp, INT); va_end (argp); for (I = 0; I <n; I ++) cout <ary [I] <Endl;} void main () {stdarg (5, 12, 64, 34, 23 );}

Finally, let's analyze the stdarg. h header file (I don't understand it too)

Typedef char * va_list;

# Define va_start _ crt_va_start
# Define va_arg _ crt_va_arg
# Define va_end _ crt_va_end

# DEFINE _ crt_va_start (AP, V) (AP = (va_list) _ addressof (v) + _ intsizeof (v ))
# DEFINE _ crt_va_arg (AP, t) (* (T *) (AP + = _ intsizeof (t)-_ intsizeof (t )))
# DEFINE _ crt_va_end (AP) (AP = (va_list) 0)
Va_list argptr;
C functions are pushed from right to left into the stack. After va_start is called,
According to the defined macro operation, _ addressof obtains the address of V, and then
Add the value of V to the address so that the AP points to the first variable parameter:

High stack address
| .......
| Function return address
| .......
| Last function parameter
| ....
| The first variable parameter of the function <-va_start after which the AP points
| Last fixed parameter of the Function
| The first fixed parameter of the Function
Stack top and low address

Then, use va_arg () to obtain the variable parameter value of type T. First, let the AP point to the next parameter:
AP + = _ intsizeof (T), and then subtract _ intsizeof (T) to make the expression result
The value before the AP, that is, the address of the parameter to be obtained, is forcibly converted to the address pointing to this parameter
Type pointer, and then use *

Finally, use va_end (AP) to initialize the AP and maintain robustness.

Example :( chenguiming)

# Include <stdio. h>
# Include <ctype. h>
# Include <stdlib. h>
# Include <stdarg. h>

Int average (INT first ,... ) // Variable Parameter function, which is also available in C ++
{
Int COUNT = 0, I = first, sum = 0;
Va_list maker; // all parameters of the va_list function can be saved as a list.
Va_start (maker, first); // you can specify the start position of the list.
While (I! =-1)
{
Sum + = I;
Count ++;
I = va_arg (maker, INT); // returns the current value of the maker list and points to the next position in the list.
}
Return sum/count;

}

Void main (void)
{
Printf ("average is: % d \ n", average (2, 3, 4,-1 ));
}

Stdarg. h in Linux

# Ifndef _ stdarg_h
# DEFINE _ stdarg_h

Typedef char * va_list;/* defines va_list as a character pointer type */

/* Amount of space required in an argument list for an ARG of type.
Type may alternatively be an expression whose type is used .*/
/* The following shows the space capacity required by the ARG parameter list of type.
Type can also be an expression of this type */

// The following sentence defines the byte length value of the type after the integer is obtained. Is a multiple of the int length (4.
# DEFINE _ va_rounded_size (type )\
(Sizeof (type) + sizeof (INT)-1)/sizeof (INT) * sizeof (INT ))

// The following function (with macro implementation) directs the AP to the first parameter of the variable parameter table passed to the function.
// You must call this function before calling va_arg or va_end for the first time.
// The _ builtin_saveregs () on the 17 rows is defined in the GCC Library Program libgcc2.c and used to save registers.
// For its description, refer to the "Target description macros" section in the GCC manual.
// "Implementing the varargs macros" section.
# Ifndef _ names __
# Define va_start (AP, lastarg )\
(AP = (char *) & (lastarg) + _ va_rounded_size (lastarg )))
# Else
# Define va_start (AP, lastarg )\
(_ Builtin_saveregs (),\
AP = (char *) & (lastarg) + _ va_rounded_size (lastarg )))
# Endif

// The macro below is used to call the function to complete a normal return. Va_end can modify the AP so that it can be called again.
// It cannot be used before va_start. Va_end must be called after all parameters are read by va_arg.
Void va_end (va_list);/* defined in gnulib * // * defined in gnulib */
# Define va_end (AP)

// The macro below is used to extend the expression so that it has the same type and value as the next passed parameter.
// For the default value, va_arg can be of the character, unsigned character, or floating point type.
// When va_arg is used for the first time, it returns the first parameter in the table.
// The next parameter. This is achieved by first accessing the AP and then adding it to point to the next item.
// Va_arg uses type to access and locate the next item. Each time va_arg is called, it modifies the AP to indicate
// The next parameter in the table.
# Define va_arg (AP, type )\
(AP + = _ va
_ Rounded_size (type ),\
* (Type *) (ap-_ va_rounded_size (type ))))

# Endif/* _ stdarg_h */

Use stdarg. h to implement variable length parameters

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.