Как это объяснить, что происходит, когда мы приводим char со знаком в int / hex? - PullRequest
0 голосов
/ 15 июня 2011
signed char num = 220; //DC in hex
printf("%02X\n", num);
printf("%d\n", num);

Я знаю, что signed char может представлять только -128~127, но почему вышеприведенные выводы:

FFFFFFDC
-36

В чем причина?

UPDATE

Мой код выше просто придуман для моего вопроса, то есть what happens when we cast signed char to int/hex

Ответы [ 4 ]

2 голосов
/ 15 июня 2011

Как вы указали, подписанный автомобиль может иметь максимальное значение 127. Причина отрицательного числа, однако, заключается в том, как символ хранится в памяти.Все целочисленные типы со знаком сохраняют последний бит для знака, где 0/1 обозначает положительный / отрицательный.Компилятор, однако, не проверяет переполнение, поэтому, когда вы попытались присвоить num значение 220, он переполнил значение в знаковый бит, так как не смог уместить его в первые 7 битов символа (символы 1 байт).В результате, когда вы пытаетесь прочитать то, что находится в памяти, он видит бит знака как брошенный, заставляя компилятор думать, что вместо того, чтобы видеть большое положительное число, как вы предполагали, он вместо этого видит небольшое отрицательное значение.Следовательно, вывод вы видите.

Редактировать Отвечая на ваш обновленный вопрос.Все, что происходит, - это то, что компилятор скопирует или расширит char, чтобы иметь 4 байта памяти, интерпретирует значение char и переписывает его в память нового int.В вашем случае программа во время выполнения будет думать, что символ имеет значение -36 вместо 220, потому что он интерпретирует эти биты как подписанный символ перед приведением.Затем, когда он выполняет приведение, он просто создает int со значением -36.

1 голос
/ 15 июня 2011

В качестве нашей отправной точки, 220 = DC в шестнадцатеричном и 11011100 в двоичном.

Первый бит является битом знака, оставляя нам значение 1011100. За дополнение до двух , еслимы дополняем его (получая 0100011), а затем добавляем один, получаем 0100100 - это 36.

Когда он преобразует подписанный символ в подписанное int, он не говорит «это будет 220, если этобез знака ", это говорит" это -36, сделать его целым из -36 ", для которого 32-разрядное представление дополнения до двух - FFFFFFDC, потому что это должно быть отрицательное значение для полного размера int (это называется знак-расширение ):

+36 as a 32-bit value: 00000000000000000000000000100100
complement:            11111111111111111111111111011011
add one:               11111111111111111111111111011100

Или, в шестнадцатеричном, FFFFFFDC.

Вот почему вы должны быть осторожны с printf("%x", ch); (и его родственниками) -- если вы намереваетесь просто получить двузначное значение, а символы должны быть подписаны, вы можете вместо этого получить восемь цифр.Всегда указывайте "unsigned char", если вам нужно, чтобы он был без знака.

0 голосов
/ 15 июня 2011

Любой тип, меньший, чем «int», преобразуется в «int» при передаче через «...».Это означает, что ваш отрицательный символ преобразован в отрицательный int, а FFF отображаются в шестнадцатеричной распечатке.

0 голосов
/ 15 июня 2011

Ваше переполнение в назначении в сочетании с расширением знака, когда вы переводите его в int для просмотра его в шестнадцатеричном формате ... см. Что происходит на фоне приведения типа без знака к целочисленному типу?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...