Ansi c -- variable parameters

Source: Internet
Author: User
Document directory
  • [Prototype]
  • [Description]
  • [Usage]
  • [Implementation Analysis]
  • [Example]
[Prototype]

Type fun (type arg1, type arg2,...

);

[Description]

It is mainly used in functions with uncertain number of parameters, such as printf.

[Usage]

Reference: glib/manual/Add. c

# Include <stdarg. h> <br/> # include <stdio. h> <br/> int add_em_up (INT count ,...) <br/>{ <br/> va_list AP; <br/> int I, sum; <br/> va_start (AP, count);/* initialize the argument list. */<br/> sum = 0; <br/> for (I = 0; I <count; I ++) <br/> sum + = va_arg (AP, INT);/* Get the next argument value. */<br/> va_end (AP);/* clean up. */<br/> return sum; <br/>}< br/> int main (void) <br/>{< br/>/* This call prints 16. */<br/> printf ("% d/N", add_em_up (3, 5, 5, 6); <br/>/* This call prints 55. */<br/> printf ("% d/N", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); <br/> return 0; <br/>}

Running result:

 

16

55

[Implementation Analysis]

To implement variable parameters, the key isHow to traverse the function list
This involves the storage order of function parameter linked lists in the stack:

The function stack entry process is roughly as follows: (for more details, refer to here.
)

  1. Function Local variables are added to the stack;
  2. Other information pointers of the called functions are written into the stack;
  3. Function return address into stack;
  4. The parameter list is added to the stack in sequence from right to left;

In this case, we can clearly define the storage order of the parameter list, as shown below:

 

Therefore, we must know the top parameter address of the stack, that is, the first parameter of the function;

 

It mainly depends on three macros defined in stdarg. h:

 

  • Void va_start (va_list arg_ptr, prev_param);/* address of the first parameter */
  • Type va_arg (va_list arg_ptr, type);/* starts from the second parameter and returns */
  • Void va_end (va_list arg_ptr);/* indicates that the mark has been completed. In fact, nothing is done */

The implementation and comments of stdarg. h are as follows:

# Ifndef _ stdarg_h <br/> # DEFINE _ stdarg_h <br/> typedef char * va_list; <br/>/* perform memory Alignment Based on the Type value */<br/> # DEFINE _ va_rounded_size (type)/<br/> (sizeof (type) + sizeof (INT)-1)/sizeof (INT) * sizeof (INT) </P> <p>/* According to the address of the first parameter lastarg, obtain the second parameter address */<br/> # define va_start (AP, lastarg) (AP = (char *) & (lastarg) + _ va_rounded_size (lastarg ))) <br/>/* completed, no need to do */<br/> # define va_end (AP) <br/>/* return the parameter value pointed to by the current AP Based on the type, AP points to the next <br/> here, the comma expression is used. The result is displayed on the left, right, and right. <Br/> aP + = _ va_rounded_size (type), pointing to the next parameter; <br/> (AP + = _ va_rounded_size (type), returning the previous parameter; <br/> */<br/> # define va_arg (AP, type)/<br/> (AP + = _ va_rounded_size (type), * (type *) (ap-_ va_rounded_size (type) <br/> # endif/* _ stdarg_h */

 

In fact, the implementation of stdarg. h varies depending on the compiler. For more information, see here.
.

 

[Example]

In this example, we can modify glib/manual/Add. C as follows: add_ex.c

# Include <stdarg. h> <br/> # include <stdio. h> <br/> int show_arg (INT count ,...) <br/>{< br/> va_list AP; <br/> int I = 1; <br/> va_start (AP, count ); /* specify the address of the first parameter */<br/> printf ("first Arg address = % d/N", (unsigned INT) AP-sizeof (count )); <br/> for (I = 1; I <= count; I ++) <br/> printf ("% d = % d/T next_addh = % d/N", I, va_arg (AP, INT), (unsigned INT) AP ); /* take the next parameter in a loop */<br/> va_end (AP);/* end */<br/> return 0; <br/>}< br/> int main (void) <br/>{</P> <p>/* We intentionally set one more Count value, <br/> the sixth value is the return address of the function */<br/> show_arg (10, 1, 2, 3, 4, 5 ); <br/> return 0; <br/>}< br/>

 

Running result: the GCC and VC compilation results are different.

 

 

Reprinted please declare to: http://blog.csdn.net/oncoding/archive/2009/09/13/4549160.aspx

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.