На что будет нацелен буквально 0x88 в c ++? - PullRequest
1 голос
/ 10 января 2012

Я думал, что литерал типа 0x88 приведёт к signed int.но вывод следующей программы отличается от моего первоначального предположения.Может ли кто-нибудь пролить некоторый свет на это и объяснить, что происходит?

printf("%hd, %hu\n", 0x88); // output: 136 (10001000), 65416 (11111111 10001000)

Если мое предположение было верным, 0x88 сначала будет приведено к signed int и станет:* При печати с %hd он будет приведен к signed short, что приведет к:

00000000 10001000

, а печать с %hd приведет к unsigned short, что снова приведет к:

00000000 10001000

Я ожидал, что выходные данные обоих printf с составят 136.

обновление : отсутствует один из параметров printfошибочно.Это должно было быть так, как вы, ребята, отметили:

printf("%hd, %hu\n", 0x88, 0x88);

Ответы [ 2 ]

5 голосов
/ 10 января 2012

В C ++ все литералы имеют тип, они не "приводятся к".Тип целочисленных литералов без дополнительного суффикса - это наименьшее целое число, достаточно большое для представления значения, но не меньше целого.

Таким образом, тип 0x88 равен int.

Таким образом, ваш printf должен быть:

printf("%d",0x88);

Обратите внимание, что:

  • Ваш printf("%hd, %hu\n", 0x88); вызывает UB, так как он имеет больше спецификаторов формата, чем параметров.
  • Использование спецификаторов формата, отличных от параметров, не приведет к приведению типов, в худшем случае также вызовет UB.Поэтому, если вы хотите использовать спецификатор формата %hd для short int, тип аргумента также должен быть одинаковым.
0 голосов
/ 10 января 2012

Остерегайтесь переменных функций.printf ожидает столько аргументов (плюс сам формат), сколько имеется спецификаторов, и здесь у вас есть 2 спецификатора, но только один аргумент для форматирования.

Если вы используете правильную строку :

#include <cstdio>

int main() {
  std::printf("%hd, %hu\n", 0x88, 0x88);
}

Вы увидите:

136, 136
...