Введение в язык Си++

         

Побитовые логические операции


Побитовые логические операции

| ^ ~

применяются к целым, то есть к объектам типа char, short, int, long и их unsigned аналогам, результаты тоже целые.

Одно из стандартных применений побитовых логических операций - реализация маленького множества (вектора битов). В этом случае каждый бит беззнакового целого представляет один член множества, а число членов ограничено числом битов. Бинарная операция интерпретируется как пересечение, | как объединение, а ^ как разность. Для именования членов такого множества можно использовать перечисление. Вот маленький пример, заимствованный из реализации (не пользовательского интерфейса) :

enum state_value { _good=0, _eof=1, _fail=2, _bad=4}; // хорошо, конец файла, ошибка, плохо

Определение _good не является необходимым. Я просто хотел, чтобы состояние, когда все в порядке, имело подходящее имя. Состояние потока можно установить заново следующим образом:

cout.state = _good;

Например, так можно проверить, не был ли испорчен поток или допущена операционная ошибка:

if (cout.state(_bad|_fail)) // не good

Еще одни скобки необходимы, поскольку имеет более высокий приоритет, чем |.

Функция, достигающая конца ввода, может сообщать об этом так:

cin.state |= _eof;

Операция |= используется потому, что поток уже может быть испорчен (то есть, state==_bad), поэтому

cin.state = _eof;

очистило бы этот признак. Различие двух потоков можно находить так:

state_value diff = cin.state^cout.state;

В случае типа stream_state (состояние потока) такая разность не очень нужна, но для других похожих типов она оказывается самой полезной. Например, при сравнении вектора бит, представляющего множество прерываний, которые обрабатываются, с другим, представляющим прерывания, ждущие обработки.

Следует заметить, что использование полей (#2.5.1) в действительности является сокращенной записью сдвига и маскирования для извлечения полей бит из слова. Это, конечно, можно сделать и с помощью побитовых логических операций, Например, извлечь средние 16 бит из 32-битового int можно следующим образом:

unsigned short middle(int a) { return (a8)0xffff }

Не путайте побитовые логические операции с логическими операциями:

!

Последние возвращают 0 или 1, и они главным образом используются для записи проверки в операторах if, while или for (#3.3.1). Например, !0 (не ноль) есть значение 1, тогда как ~0 (дополнение нуля) есть набор битов все-единицы, который обычно является значением -1.



Содержание раздела