The realization principle of printf

      To understand the realization of the variable parameter function, we must first clarify a few questions:
1: The function has several parameters.
2: How does the function access these parameters.
3: After the access is completed, how to release these parameters from the stack.

Function variable

     For the C language, its calling rules follow the _cdedl calling rules. In the _cdedl rule:

    1. The parameters are pushed into the stack from right to left
    2. The caller is responsible for cleaning up the stack
    3. The number and type of parameters will not cause errors in the compilation stage

    The statement of printf: int _cdecl printf(const char* format, …); // _cdecl is the default calling method of C and C++ programs

     The stack grows from a high address to a low address, and the parameters are pushed onto the stack from right to left, so the high address of the stack is the rightmost parameter of printf. With

printf("%d %f %c %s\n", 3, 5.40, A, "hello world"); As an example, the stack structure is as follows:

       How do I know the type of the variable parameter inside the called function? For the printf function, the caller notified the callee (implementer of printf) through the %+ format character in the first fmt parameter.

 Format analysis

       Scan the characters in the format parameter, if it is a normal character, print it out. If it is %, it means that there may be a format character in the back, which needs to be detected, and then pop the specified type from the bottom of the stack (in fact, the position of the first parameter) The data is output in the specified format (decimal, hexadecimal, specified width, specified precision, etc.). It is basically a process of string parsing.

typedef char *va_list;
#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )                          /* 1 */
#define va_start(va_list  ap, format) ( ap = (va_list)&format+ _INTSIZEOF(format) )           /* 2 */     
#define va_arg(va_list  ap,type)  
              ( *(type*)((ap += _INTSIZEOF(type)) -_INTSIZEOF(type)) )                                   /* 3 */
#define va_end(va_list  ap)  ( ap = (va_list)0 )                                                                      /* 4 */

1: align sizeof(n) according to sizeof(int)

2: Initialize the parameter pointer ap, and assign the first parameter address on the right of format to ap

3: type is used to name the current parameter type, get the value of ap pointing to the parameter, and make ap point to the next parameter

4: It does not have any effect in some simple implementations. In some implementations, ap may be changed to an invalid value. Here, the ap pointer points to NULL.

 

 The c standard requires va_start and va_end to appear paired in the same function. So far, the steps to deal with multi-parameter functions are
1: First, ensure that the function has at least one parameter, and at the same time use...parameters to declare that the function is a variable parameter function.
2: Use the va_start(ap,format) macro to initialize the parameter pointer within the function.
3: Use va_arg(ap,type) to take the parameter values ​​one by one from left to right.

 The general form of printf() format conversion is as follows:

%[flags][width][.prec][type]
prec has the following situations:
                    the minimum number of digits of a positive integer
                    represents the number of decimal places in a floating point number. The
                    %g format represents the maximum valid value. The
                    %s format represents characters
                    If the maximum length of the string is the * symbol, the next parameter value is the maximum length
width: the minimum length of the output. If this output parameter is not a numeric value but an * symbol, it means that the following parameter is used as the output length.

 

 There are also some useful links:

The principle of printf

The realization principle of printf function

The realization principle of variable parameter function in C language

Detailed usage of printf()

Analysis of the principle of printf printing function

Guess you like

Origin blog.csdn.net/sy_123a/article/details/108448355