int x; scanf() с%d и printf() с%c
int x; Таким образом, для переменной будет 2 байта памяти. Теперь, если я ввел 66 и поскольку scanf() с%d, 66 будет храниться в 2-байтовой памяти, потому что переменная объявлена как int.
Теперь в printf() с%c следует собрать данные только из одной байтовой памяти для отображения.
Но%c отображается правильно B, получая правильные данные 66 из памяти для отображения.
Почему%c не просто получает данные из одного байта?
3 ответа
%c
ожидает int
аргумент, из-за продвижения аргумента по умолчанию для функций vararg. Другими словами, все следующее в точности эквивалентно:
int x = 66;
char y = 66;
printf("%c", x); // A
printf("%c", (char)x); // B
printf("%c", y); // C
printf("%c", (int)y); // D
Так что все, что происходит, это printf
интерпретирует int
значение 66 в виде кода ASCII 1 и печать соответствующего символа.
1. Обратите внимание, что ASCII технически является проектным решением, определяемым реализацией. Просто в подавляющем большинстве случаев.
%c
спецификатор преобразования в printf()
Заявление ожидает int
аргумент. Далее, так как printf()
является переменной функцией, char
превращается в int
в силу продвижения аргумента по умолчанию.
int
аргумент, который передается printf()
соответствует %c
Спецификатор затем преобразуется в unsigned char
от printf()
перед печатью. Обратите внимание, что преобразование signed
целочисленный тип unsigned
Целочисленный тип четко определен в C и не требует сбора "данных только из одного байта". Скорее, если новый тип может содержать исходное значение, значение остается неизменным; в противном случае значение, большее максимального значения для нового типа, добавляется (или вычитается из) к старому (signed
) значение. Например, int
ценность -1
будет преобразован в unsigned char
значение (при условии UCHAR_MAX
255) из -1 + 256
, или же 255
, который находится в пределах диапазона unsigned char
,
Обратите внимание, что int
со значением 66
будет неизменным в преобразовании в unsigned char
, так как 66 находится в пределах диапазона unsigned char
, UCHAR_MAX
должно быть минимум 255.
Независимо от того, как аргумент передается, %c
спецификатор формата всегда преобразует свой аргумент в unsigned char
перед печатью. Так, %c
всегда печатает один байт.
Ваше утверждение о том, что %c
получает данные из более чем одного байта безосновательно. Представленный пример не показывает никаких доказательств обратного - 66
это число, которое умещается в один байт.
Сложности передачи аргументов с переменным числом аргументов (да, они передаются как int
) не имеют отношения к наблюдаемому поведению в этом случае.