The printf
function has the following declaration:
int printf(const char *format, ...);
The first argument must be a pointer to a char
array, but any additional arguments can be of any type, so it's not a compiler error if a format specifier mismatches the parameter (although it is undefined behavior).
This still works however because of what %c
expects. From the man page:
If no l modifier is present, the int argument is converted to an
unsigned char, and the resulting character is written. If an l
modifier is present, the wint_t (wide character) argument is
converted to a multibyte sequence by a call to the wcrtomb(3)
function, with a conversion state starting in the initial state,
and the resulting multibyte string is written.
From the above passage, %c
actually expects an int
and converts it to an unsigned char
for printing. So if that's the case why does passing an actual char
work? That is because of integer promotions. Any integer type smaller than int
is promoted to int
anyplace an int
can be used. Since printf
is variadic it can't check the types of its arguments, so a char
passed to printf
will get promoted to int
when the function is called.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…