Функция printf
имеет следующее объявление:
int printf(const char *format, ...);
Первый аргумент должен быть указателем на массив char
, но любые дополнительные аргументы могут быть любого типа, поэтому это неошибка компилятора, если спецификатор формата не соответствует параметру (хотя он равен неопределенному поведению).
Однако это все равно работает из-за ожиданий %c
.Со страницы руководства:
Если модификатор l отсутствует, аргумент int преобразуется в символ без знака , и полученный символ записывается.Если присутствует модификатор l, аргумент wint_t (широкий символ) преобразуется в многобайтовую последовательность путем вызова функции wcrtomb (3), причем состояние преобразования начинается в начальном состоянии, а полученная многобайтовая строка записывается.
Из приведенного выше отрывка %c
фактически ожидает int
и преобразует его в unsigned char
для печати.Так что, если это так, то почему фактическая char
работает?Это из-за целочисленных повышений .Любой целочисленный тип, меньший int
, повышается до int
в любом месте, где можно использовать int
.Поскольку printf
является переменным, он не может проверять типы своих аргументов, поэтому char
, переданный в printf
, будет повышен до int
при вызове функции.