Почему char, указанный как целое число в printf, печатается правильно - PullRequest
0 голосов
/ 23 октября 2018

Почему работает следующий код?

char c = 'A';
printf("%d - size: %d", c, sizeof(c));

Распечатывает:

65 - size: 1

Почему вывод не мусор, так как int обычно имеет длину 4 байта, и мы можемчетко видно, что длина символа составляет 1 байт.Компилятор делает неявный разговор?

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Существует специальное правило для функций со списками аргументов переменной длины, например printf.В части переменной длины списка аргументов все целочисленные аргументы, меньшие int, переводятся в int, а float в double.Таким образом, оказывается, что совершенно нормально напечатать символ (или short), используя %d.

Эти продвижения аргументов по умолчанию в конечном итоге учитывают ряд аномалий в printf.Можно подумать, что правильными спецификаторами формата для char, short, int, float и double являются %hhd, %hd, %d, %f и %lfсоответственно.Но на самом деле вы можете уйти с %d, %d, %d, %f и %f.printf в основном игнорирует модификатор l для чисел с плавающей запятой и, кажется, игнорирует модификатор h для целых чисел.(На самом деле h может иметь значение в неясных случаях, как объясняет chux в комментарии.)

0 голосов
/ 23 октября 2018

Любой целочисленный тип с рангом ниже int равен , повышается до int или unsigned int каждый раз, когда он используется в выражении.Это указано в разделе 6.3.1.1p2 стандарта C:

В выражении может использоваться следующее, где могут использоваться int или unsigned int:

  • Объект или выражение с целочисленным типом (кроме int или unsigned int), чей ранг целочисленного преобразования меньше или равен рангу int и unsigned int.
  • Битовое поле типа _Bool, int,int со знаком или без знака.

Если int может представлять все значения исходного типа (как ограничено шириной для битового поля), значение преобразуется в int;в противном случае он конвертируется в беззнаковое целое.Они называются целочисленными продвижениями.

Все остальные типы не изменяются целочисленными продвижениями

Вот что происходит в этом случае, так как функция printf неявно не знаеттип его параметров во время компиляции.Таким образом, аргумент char переводится в int, и использование %d для форматирования является допустимым.

...