Int Arg (unsigned char a); <br/> int main () <br/>{< br/> float B = 11.0; <br/> Arg (B ); <br/> return 0; <br/>}< br/> int Arg (unsigned char a) <br/>{< br/> float c = 5.0; <br/> float d = 6.6; <br/> printf ("Arg = % d/N", a); <br/> printf ("/N "); <br/> printf ("c = % F (float)/n", c); <br/> printf ("c = % d (INT)/n ", c); <br/> printf ("(INT) C = % d (INT)/n", (INT) C ); <br/> printf ("(unsigned char) C = % d (INT)/n", (unsigned char) C ); <br/> printf ("/N"); <br/> printf ("d = % F (float)/n", d ); <br/> printf ("d = % d (INT)/n", d); <br/> printf ("(INT) d = % d (INT) /n ", (INT) d); <br/> printf (" (unsigned char) d = % d (INT)/n ", (unsigned char) D ); <br/> return 0; <br/>}
Output result:
Arg = 11 <br/> C = 5.000000 (float) <br/> C = 0 (INT) <br/> (INT) C = 5 (INT) <br/> (unsigned char) C = 5 (INT) <br/> d = 6.600000 (float) <br/> d = 1610612736 (INT) <br/> (INT) d = 6 (INT) <br/> (unsigned char) d = 6 (INT)
This code mainly aims to explain: When a function parameter is passed in, it performs type conversion, that is, the parameter has been intercepted when it is imported into the stack (for example, long is passed into char); it also includes the storage result of forced type conversion, different from output in a format that does not conform to the variable type.
From this code, I thought of the implementation of printf. I thought of printf. I had to first parse the format character in the const char * STR to determine the pointer type and move the size of va_list. The following is a great explanation of printf !!
Int
Defun (printf, (format), const char * Format
DOTS)
{
Va_list ARG;
Int done;
Va_start (ARG, format );
Done = vprintf (format, ARG );
Va_end (ARG );
Return done;
}
We can see that
Printf
Actually, what is called internally is
Vprintf
, View
Vprintf. c
Content, we can see
Vprintf
In fact, it is through
Vfprintf
The function prototype is as follows:
Int defun (vfprintf, (S, format, argS ),
Register File * s
And const char * Format and va_list
ARGs)
The overall execution structure of this function is as follows:
Register const char * F;
//
We can see that
F
Is
Const
Char
Pointer
F = format;
While (* F! = '/0 ')
{
...
If (* F! = '% ')
{
...
}
If (* f = '% ')
{
Fc = * f ++;
...
Switch (FC)
{
Case 'D ':
...
Case 'C ':
...
....
}
}
}
From the above structure, we can see that the function first reads the characters in the string and then compares them one by one.
%
, Use immediately
Switch... case
Subsequent characters of structure judgment
In each
Case
The statement block contains the following statements:
Nextarg (...);
Outchar (...);
Nextarg ()
Is a macro with the following macro definitions:
# Define castarg (VAR, argtype, casttype )/
Var = (casttype) va_arg (ARGs,
Argtype)
# Define nextarg (VAR, type) castarg (VAR, type,
Type)
First Appearance
Va_arg
We are very familiar with it. The macro is used to read variable parameters.
ARGs
. That is, use the stack top pointer to read
Stack content.
Outchar (...)
It is also a macro. Its definition is as follows:
# Define outchar (X)
/
Do
/
{
/
Register const int
Outc = (X );
/
If (putc (outc, S)
= EOF)
/
Return (-1 );
/
Else
/
++ Done;
/
} While (0)