Выбрать главу

Для представления информации, которая содержится в байте состояний, можно использовать следующие битовые поля.

struct status_type {

 unsigned delta_cts: 1;

 unsigned delta_dsr: 1;

 unsigned tr_edge: 1;

 unsigned delta_rec: 1;

 unsigned cts: 1;

 unsigned dsr: 1;

 unsigned ring: 1;

 unsigned rec_line: 1;

} status;

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

status = get_port_status();

if(status.cts) cout << "Установка в исходное состояние";

if(status.dsr) cout << "Данные готовы";

Чтобы присвоить битовому полю значение, достаточно использовать такую же форму, которая обычно применяется для элемента структуры любого другого типа. Например, следующая инструкция очищает битовое поле ring:

status.ring = 0;

Как видно из этих примеров, доступ к каждому битовому полю можно получить с помощью оператора "точка". Но если общий доступ к структуре осуществляется через указатель, необходимо использовать оператор "->".

Следует иметь в виду, что совсем необязательно присваивать имя каждому битовому полю. Это позволяет обращаться только к нужным битам, "обходя" остальные. Например, если вас интересуют только биты cts и dsr, вы могли бы объявить структуру status_type следующим образом.

struct status_type {

 unsigned : 4;

 unsigned cts: 1;

 unsigned dsr: 1;

} status;

Обратите здесь внимание на то, что биты после последнего именованного dsr нет необходимости вообще упоминать.

В структуре можно смешивать "обычные" члены с битовыми полями. Вот пример.

struct emp {

 struct addr address;

 float pay;

 unsigned lay_off: 1; // работает или нет

 unsigned hourly: 1: // почасовая оплата или оклад

 unsigned deductions: 3: // удержание налога

};

Эта структура определяет запись по каждому служащему, в которой используется только один байт для хранения трех элементов информации: статус служащего, характер оплаты его труда (почасовая оплата или твердый оклад) и налоговая ставка. Без использования битовых полей для хранения этой информации пришлось бы занять три байта.

Использование битовых полей имеет определенные ограничения. Программист не может получить адрес битового поля или ссылку на него. Битовые поля нельзя хранить в массивах. Их нельзя объявлять статическими. При переходе от одного компьютера к другому невозможно знать наверняка порядок следования битовых полей: справа налево или слева направо. Это означает, что любая программа, в которой используются битовые поля, может страдать определенной зависимостью от марки компьютера. Возможны и другие ограничения, связанные с особенностями реализации компилятора C++, поэтому имеет смысл прояснить этот вопрос в соответствующей документации.

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

Объединения

Объединение состоит из нескольких переменных, которые разделяют одну и ту же область памяти.

Объединение состоит из нескольких переменных, которые разделяют одну и ту же область памяти. Следовательно, объединение обеспечивает возможность интерпретации одной и той же конфигурации битов двумя (или более) различными способами. Объявление объединения, как нетрудно убедиться на следующем примере, подобно объявлению структуры.

union utype {

 short int i;

 char ch;

};

Объявление объединения начинается с ключевого слова union.

Здесь объявляется объединение, в котором значение типа short int и значение типа char разделяют одну и ту же область памяти. Необходимо сразу же прояснить один момент: невозможно сделать так, чтобы это объединение хранило и целочисленное значение, и символ одновременно, поскольку переменные i и ch накладываются (в памяти) друг на друга. Но программа в любой момент может обрабатывать информацию, содержащуюся в этом объединении, как целочисленное значение или как символ. Следовательно, объединение обеспечивает два (или больше) способа представления одной и той же порции данных. Как видно из этого примера, объединение объявляется с помощью ключевого слова union.