В этих примерах подразумевается, что младший бит расположен справа, тип char содержит 8 битов, а тип int — 32 бита

// 0233 - восьмеричный литерал (см. раздел 2.1.3)

unsigned char bits = 0233; 1 0 0 1 1 0 1 1

bits << 8  // bits преобразуется в int и сдвигается влево на 8 битов

0 0 0 0 0 0 0 0  0 0 0 0 0 0 0 0  1 0 0 1 1 0 1 1  0 0 0 0 0 0 0 0

bits << 31 // сдвиг влево на 31 бит отбрасывает крайние левые биты

1 0 0 0 0 0 0 0  0 0 0 0 0 0 0 0  0 0 0 0 0 0 0 0  0 0 0 0 0 0 0 0

bits >> 3  // сдвиг вправо на 3 бита отбрасывает 3 крайних правых бита

0 0 0 0 0 0 0 0  0 0 0 0 0 0 0 0  0 0 0 0 0 0 0 0  0 0 0 1 0 0 1 1

Побитовый оператор NOT

Побитовый оператор NOT (~) (bitwise NOT operator) создает новое значение с инвертированными битами своего операнда. Каждый бит, содержащий 1, превращается в 0; каждый бит, содержащий 0, — в 1.

unsigned char bits = 0227; 1 0 0 1 0 1 1 1

~bits

1 1 1 1 1 1 1 1  1 1 1 1 1 1 1 1  1 1 1 1 1 1 1 1  0 1 1 0 1 0 0 0

Здесь операнд типа char сначала преобразуется в тип int. Это оставляет значение неизменным, но добавляет нулевые биты в позиции старших разрядов. Таким образом, преобразование в тип int добавляет 24 бита старших разрядов, заполненных нулями. Биты преобразованного значения инвертируются.

Побитовые операторы AND, OR и XOR

Побитовые операторы AND (&), OR (|) и XOR (^) создают новые значения с битовым шаблоном, состоящим из двух их операндов.

unsigned char b1 = 0145; 0 1 1 0 0 1 0 1

unsigned char b2 = 0257; 1 0 1 0 1 1 1 1

b1 & b2   Все 24 старших бита 0   0 0 1 0 0 1 0 1

b1 | b2   Все 24 старших бита 0   1 1 1 0 1 1 1 1

b1 ^ b2   Все 24 старших бита 0   1 1 0 0 1 0 1 0

Каждая битовая позиция результата побитового оператора AND (&) содержит 1, если оба операнда содержат 1 в этой позиции; в противном случае результат — 0. У побитового оператора OR (|) бит содержит 1, если один или оба операнда содержат 1; в противном случае результат — 0. Для побитового оператора XOR (^) бит содержит 1, если любой, но не оба операнда содержат 1; в противном случае результат — 0.

Побитовые и логические (см. раздел 4.3) операторы нередко путают. Например, путают побитовый оператор & с логическим &&, побитовый | с логическим || и побитовый ~ с логическим !.

Использование побитовых операторов

Рассмотрим пример использования побитовых операторов. Предположим, что есть класс с 30 учениками. Каждую неделю класс отвечает на контрольные вопросы с оценкой "сдано/не сдано". Результаты всех контрольных записываются, по одному биту на ученика, чтобы представить успешную оценку или нет. Каждую контрольную можно представить в виде беззнакового целочисленного значения.

unsigned long quiz1 = 0; // это значение используется

                         // как коллекция битов

Переменная quiz1 определена как unsigned long. Таким образом, на любой машине она будет содержать по крайней мере 32 бита. Переменная quiz1 инициализируется явно, чтобы ее значение было определено изначально.

Учитель должен быть способен устанавливать и проверять отдельные биты. Например, должна быть возможность установить бит, соответствующий ученику номер 27, означающий, что этот ученик сдал контрольную. Чтобы указать, что ученик 27 прошел контрольную, создадим значение, у которого установлен только бит номер 27. Если затем применить побитовый оператор OR к этому значению и значению переменной quiz1, то все биты, кроме бита 27, останутся неизменными.

В данном примере счет битов переменной quiz1 начинается с 0, соответствующего младшему биту, 1 соответствует следующему биту и т.д.

Чтобы получить значение, означающее, что ученик 27 сдал контрольную, используется оператор сдвига влево и целочисленный литерал 1 типа unsigned long (см. раздел 2.1.3).

1UL << 27 // создает значение только с одним установленным битом

          // в позиции 27

Перейти на страницу:

Похожие книги