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) не имеют отношения к наблюдаемому поведению в этом случае.

Другие вопросы по тегам