Ваше замешательство здесь вполне понятно! Проблема связана с характером двух C++
операторов, <<
и >>
. В самые первые дни эволюции языка от C
это были исключительно , используемые в качестве так называемых операторов "сдвига битов", где <<
будет сдвигать значение в целое число на заданное числобиты влево, и >>
будет сдвигать биты вправо. Итак, учитывая 2
для 16-разрядного целого числа, value
, его двоичное представление будет:
0000000000000010
Выражение value << 2
сдвигает все биты в целых 2 местах на левый ;все биты, сдвинутые за «верх» (бит № 15), теряются, а «пробелы», созданные справа, заполняются нулями, давая:
0000000000001000
, что является двоичным представлением числа 8
.
Выражение value >> 2
сдвигает все биты 2 на вправо ;все биты, сдвинутые за пределы «дна» (бит № 0), теряются, а пробелы справа заполняются нулями. Таким образом, в вашем случае, единственный бит 1
теряется (падает с конца), и общий value
заканчивается как ноль.
Теперь, когда C++
концепция stream пришли, символы оператора были необходимы для ввода и вывода таких потоков (будь то string streams или file streams, например cout
в вашем коде). Для них были выбраны операторы <<
и >>
, так как они «выглядят» как то, что они на самом деле делают (стрелки-подобные индикаторы движения). К счастью, язык C++
позволяет переопределять из любого оператора для определенного типа переменной (это называется «перегрузка оператора») и, если вы посмотрите настандартный заголовок <iostream>
, вы увидите что-то подобное в определении / объявлении класса ostream
:
ostream& operator<< (int val);
//.. similar lines for types other than int
Эта «перегрузка оператора» кодируется в исходном коде стандартной библиотеки как запись отформатированноговерсия val
для файла, представленного данным объектом ostream
(например, cout
).
Не стесняйтесь запрашивать дополнительные разъяснения и / или объяснения.
PS: Как провокатор упражнений / мыслей: что произойдет, если убрать скобки из двух строк кода?
PPS: Относительно использования битов- операторы сдвига для умножения или деления на степени 2: это лениво и потенциально опасно, когда может произойти смена знака;особенно для отрицательных чисел! См. cppreference.com (выделение жирным шрифтом):
Для отрицательного а поведение << b равно <strong>undefined .
Для беззнакового a и для подписанного и неотрицательного a значение a >> b является целой частью a / 2 ^ b.
Для отрицательного a значение a >> b равно * 1076. * определяется реализацией (в большинстве реализаций выполняется арифметическое смещение вправо, поэтому результат остается отрицательным).