В C сдвиг влево (char) 0xFF на 8 и привести его к int

StackOverflow https://stackoverflow.com/questions/1097130

  •  11-09-2019
  •  | 
  •  

Вопрос

При сдвиге (char) 0xff на 8 влево и приведении его к int мы получаем -256 или 0xffffff00.Может кто-нибудь объяснить, почему это должно произойти?

#include <stdio.h>
int main (void)
{   
    char c = 0xff;
    printf("%d %x\n", (int)(c<<8),(int)(c<<8));
    return 0;
}

Выход:

-256 ffffff00
Это было полезно?

Решение

char может быть подписанным или беззнаковым — это определяется реализацией.Вы видите эти результаты, потому что char подписывается по умолчанию в вашем компиляторе.

Для знакового символа 0xFF соответствует −1 (так работает дополнение до двух).Когда вы пытаетесь переместить его, он сначала повышается до int а затем сдвинули - вы фактически получите умножение на 256.

Итак, это код:

char c = 0xFF; // -1
int shifted = c << 8; //-256 (-1 * 256)
printf( "%d, %x", shifted, shifted );

Другие советы

Когда я впервые рассмотрел проблему, мое первоначальное мнение заключалось в том, что символ 'c' следует сдвинуть влево на 8 бит - все 8 бит отбрасываются, а пустой символ затем будет преобразован в целое число со значением 0.

Небольшое исследование показывает Обычные унарные преобразования - здесь для уменьшения большого количества арифметических типов преобразования применяются автоматически к операндам унарных операторов '!', '-', '~' и '*', и к каждому из операндов бинарных операторов '<<' и '>>'.

Поэтому символ 'c' преобразуется в int первый, затем сместился влево, дав ответ, который вы видите.

Ты узнаешь что-то новое каждый день!

c преобразуется в int до завершения операции сдвига.Предполагая, что ваша реализация по умолчанию подписывает символы, это означает, что вы получите 0xffffffff, который затем сдвигается влево, чтобы дать результат.

Если вы превратите c в беззнаковый символ, вы получите то, что ожидаете.

char — это не что иное, как подписанный символ.Таким образом, char c = 0xFF будет -1.Если вы оставите сдвиг -1 на 8 бит, вы получите -256.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top