Functions with variable number of parameters in C

Source: Internet
Author: User

I. What are variable parameters in C programming, we sometimes encounter functions with variable number of parameters, such as the printf () function, whose function prototype is: int printf (const char* format, ...); In addition to having a parameter format fixed, the number and type of parameters followed are variable (with three dots "..." to make the parameter placeholder), the actual invocation can have the following form:        printf ("%d", I);        printf ("%s", s);        printf ("The number is%d, string is:%s", I, s);    These things are familiar to everyone. But the question of how to write a variable-parameter C function and how the function compiler for these mutable parameters is implemented has been bothering me for a long time. This paper discusses this problem, hoping to have some help. Second, the processing of variable parameters in the compiler we know that va_start,va_arg,va_end is defined macro in stdarg.h , because 1) Hardware platform different 2) compiler, so the definition of the macro is different, the following look at the code in vc++6.0 stdarg.h (the path of the file is the VC installation directory \vc98\include\stdarg.h
 typedef char * VA_LIST; #define _INTSIZEOF (N) ((sizeof (n) + sizeof (int)-1) & ~ (sizeof (int)-1)) #define VA_START (ap,v) (AP = (V a_list) &v + _intsizeof (v)) #define VA_ARG (Ap,t) (* (t *) (AP + = _intsizeof (t))-_intsizeof (t)) # Define Va_end (AP) (AP = (va_list) 0) 
&v is the starting address of the last fixed parameter, plus its actual footprint , Span style= "color: #ff0000;" > You get the start memory address of the first variable parameter . So we run Va_start (AP, V) later,  down , the memory address of the top pointer is lower than the bottom of the stack pointer,       So the advanced stack of data is stored in memory at the high address. (2) in the majority of C compilers such as VC, by default, , so The memory model after the argument is in the stack is as follows: The address of the last fixed parameter is below the first mutable parameter and is continuously stored. 
|--------------------------||      Last mutable parameter | High memory address |--------------------------| |     --------------------------||        Nth variable parameter |                                    ->va_arg (arg_ptr,int) after arg_ptr refers to the place, |        |     That is, the address of the nth variable parameter. |---------------|     |--------------------------||        First variable parameter |                                    ->va_start (Arg_ptr,start) after arg_ptr refers to the place |        |     The address of the first variable parameter |---------------|                          |--------------------------||     ||       Last Fixed parameter |        Start address for Start |---------------|   
.................| -------------------------- ||                           |  | --------------- |     Low memory address at
(4) Va_arg (): With the good foundation of Va_start, we get the address of the first variable parameter, the task in Va_arg () isgets the value of this parameter according to the specified parameter type, and moves the pointer to the starting address of the next parameter. Therefore, now to see va_arg () Implementation should be aware of: #define VA_ARG (Ap,t) (* (T *) ((AP + = _intsizeof (t))-_intsizeof (t)) This macro did two things, ① with the user input type name to the parameter address coercion type conversion, the user needs to get the value ② calculate the actual size of this parameter, the pointer to the end of this parameter, that is, the first address of the next parameter for subsequent processing. (5) Explanation of Va_end macro: x86 platform is defined as ap= (char*) 0;make the AP no longer point to the stack, but as null.Some are directly defined as ((void*) 0) so that the compiler does not generate code for Va_end, such as the one defined by GCC on the Linux x86 platform. Here are a few things to note: Because the address of the parameter is used for the Va_start macro, the parameter cannot be declared as a register variable or as a function or an array type. The description of Va_start, Va_arg, Va_end is these, we should note that the definition of different operating systems and hardware platforms are somewhat different, but the principle is similar. Three, the variable parameter in programming to pay attention to the problem because Va_start, Va_arg, Va_ End and so on define macro, so it seems very foolish, the type and number of variable parameter is completely controlled by program code in this function, it is not able to intelligently recognize the number and type of different parameters. One would ask: Is it true that the intelligent identification parameters are not implemented in printf? That's because the function printf parses the type of the parameter from the fixed parameter format string, and then calls Va_arg to get the variable argument. That is, If you want to implement intelligent identification of variable parameters, you need to make judgments in your own programs. For example, in section 7.3 of the classic textbook "The C programming language" in C, a possible implementation of printf is given, which is not described here for reasons of length. Iv. Summary: 1. The three macros in the standard C library are only used to determine the memory address of each parameter in a mutable parameter list, and the compiler does not know the actual number of arguments. 2, in the actual application of the code, the programmer must consider the method of determining the number of parameters, such as ⑴ in the fixed parameters of the flag-printf function is used this method. There are also examples later. ⑵ preset A special end tag, that is, to enter a variable parameter, the call to the last variable parameter to set the value of this special value, in the function body based on this value to determine whether the end of the parameter. The code earlier in this article is to use this approach. Regardless of the approach, programmers should tell the caller their own conventions in the documentation. 3, the key to realize the variable parameters is to find a way to obtain the address of each parameter, the method of obtaining the address is determined by the following factors: ① function stack growth Direction ② parameter in the stack order ③cpu the alignment ④ memory address of the expression mode combined with the source code, we can see that the va_list implementation is determined by the ④, _ The introduction of Intsizeof (n) is determined by ③, he and ①② together to determine the implementation of Va_start, the last Va_end is the embodiment of a good programming style, will no longer use the pointer to null, this can prevent later misoperation. 4, after the address, and then combined with the type of parameters, the programmer can correctly handle parameters. Understand the above points, I believe that a slightThe reader can write the implementation that is appropriate for their own machine. 
 Overview (Synopsis) #include <stdio.h>int printf (const char *format, ...); int fprintf  (FILE *stream, const char *format, ) int sprintf (char *str, const char *format, ...); int snprintf (char *str, size_t size, const char *format, ...); 
vfprintf (FILE *stream, const char *format, va_list ap); int vsprintf (char *str, const char *format, va_list AP); int Vsnpri NTF (char *str, size_t size, const char *format, va_list AP);
These functions return the number of characters printed (not including the ' + ' at the end of the string). The output of snprintf and vsnprintf does not exceed the size byte (including the end of ' + '), and if the output is truncated because of this restriction, the function returns-1.
Log (const char* format, ...)    {        va_list ap;        Va_start (AP, format);        vfprintf (stderr, format, AP);        fprintf (stderr, "\ n");        Va_end (AP);    }

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Functions with variable number of parameters in C

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.