Операция сдвига влево для 8-битного целого числа без знака

Я пытаюсь понять операторы сдвига в C/C++, но они доставляют мне неприятности.

У меня есть 8-битное целое число без знака, инициализированное значением, например, скажем, 1.

uint8_t x = 1;

Насколько я понимаю, в памяти он представлен как |0|0|0|0|0||0||0||1|. Теперь, когда я пытаюсь изменить переменную x на 16 бит, я надеюсь получить результат 0. Но, к моему удивлению, я получаю 65536. Я определенно упускаю что-то, чего я не могу получить.

Вот мой код:

#include <iostream>

int main() {
    uint8_t x = 1;
    std::cout<<(x<<16)<<"\n";
    return 0;
}

Это наивный вопрос, но он меня очень беспокоит.


person Pankaj Mishra    schedule 07.02.2020    source источник


Ответы (1)


В этом выражении

x<<16

целочисленные продвижения применяются к обоим операндам. Таким образом, результатом выражения является объект типа int.

Попробуйте следующую демонстрационную программу

#include <iostream>
#include <iomanip>
#include <type_traits>
#include <cstdint>


int main() 
{
    uint8_t x = 1;

    std::cout << std::boolalpha << std::is_same<int, decltype( x<<16 )>::value << '\b';

    return 0;
}

Его выход

true

Из стандарта С++ (операторы сдвига 8.8)

  1. ... Операнды должны быть целочисленного типа или типа перечисления без области действия, и выполняются интегральные продвижения. Тип результата соответствует повышенному левому операнду.
person Vlad from Moscow    schedule 07.02.2020
comment
Пожалуйста, поправьте меня, если я ошибаюсь, операнд 16 представляет собой целое число из 32 бит (при условии, что целое число равно 32 битам), поэтому, применяя его с x (или 8 бит), он также повышает его до 32 бит и наконец, результат имеет тип int (32 бита). Я прав ? - person Pankaj Mishra; 07.02.2020
comment
@PankajMishra Смотрите мой обновленный пост. - person Vlad from Moscow; 07.02.2020
comment
Очень ясно, теперь. Спасибо. Проголосовал. - person Pankaj Mishra; 08.02.2020