В C a char
означает то же, что и байт; это наименьшая адресуемая часть памяти, а также наименьший из целочисленных типов. 49 представляет собой целочисленную константу типа int
, имеющую значение 49
. '1'
является символьной константой, которая также имеет тип int
! И на ASCII-системах '1'
в качестве значения 49 (код ASCII символа 1
).
printf
спецификатор преобразования %d
ожидает, что соответствующий аргумент будет int
, значение которого затем печатается в десятичной системе. Остальные аргументы после строки формата подлежат рекламным акциям по умолчанию; каждый целочисленный тип, меньший, чем int
, составляет int
; и float
- double
. Так как i
имеет целочисленный тип, меньший, чем int
, его значение (49) теперь повышается до int и до printf
оно выглядит точно так же, как если бы было задано любое другое целочисленное значение 49.
Для печати символа, характер которого код 49
, вам нужно использовать спецификатор %c
преобразования; printf
выдает 1
, который является символом кода 49; даже сейчас, аргумент повышен до int
и printf
внутренне преобразует это значение к unsigned char
, который затем будет выводиться (source):
гр
[...] int
аргумент преобразуется к unsigned char, и полученный символ записывается. [...]
Добавление: в коде
char i = 49.012;
printf("%f", i);
49.012
является значение типа double
; это преобразуется в целое число целых чисел путем измельчения десятичных знаков, поэтому значение, хранящееся в i
, равно , но снова 49; который можно доказать, напечатав его %d
. Теперь %f
ожидает, что соответствующий аргумент имеет тип double
, но i
вместо этого преобразуется в int
; использование аргумента неправильного типа при вызове printf
имеет неопределенное поведение, то есть все может случиться. Если компилирует с gcc -Wall
, получают следующее сообщение об ошибке:
предупреждение: формат %f
ожидает аргумент типа double
, но аргумент 2 имеет тип int
[-Wformat =]
"% d" говорит печати целое число, вы не питали его целым числом, поэтому он делает все возможное. Как правило, это не очень хорошо, но [variadic promotion] (http://en.cppreference.com/w/cpp/language/variadic_arguments) экономит ваш бекон здесь. – user4581301
'char' - целочисленный тип, и хотя обычно он более узкий, чем' int', он преобразуется в 'int' при передаче функции, подобной' printf() ', с помощью списка переменных аргументов. – Dmitri
Все вышеприведенные комментарии должны быть ответом, а не комментарием ... – Phong