Битовые поля
Цель лекции: изучить понятие, объявление и размещение в памяти битовых полей, доступ к битовым полям структуры или объединения и научиться решать задачи с использованием битовых полей на языке C++.
В отличие от других языков программирования С++ имеет структуру, называемую битовыми полями (полями битов), которая позволяет работать с отдельными битами. Битовое поле – это особый компонент структуры, определяющий длину отдельного ее элемента. Битовые поля полезны по нескольким причинам.
- Если ограничено место для хранения информации, можно сохранить несколько логических переменных в одном байте.
- Некоторые интерфейсы устройств передают информацию, закодировав биты в один байт.
- Некоторым процессам кодирования необходимо получить доступ к отдельным битам в байте.
Хотя все эти функции могут выполняться с помощью битовых операторов, битовые поля могут внести большую ясность в программу. Метод использования битовых полей для доступа к битам основан на структурах.
Битовое поле – это элемент структуры, определенный как некоторое число битов, обычно меньшее, чем число битов в целом числе (оно по величине не превосходит машинного слова и зависит от реализации компилятора). Они предназначены для экономного размещения в памяти данных небольшого диапазона, обеспечивают удобный доступ к отдельным битам данных. Кроме того, с помощью битовых полей можно формировать объекты с длиной внутреннего представления, не кратной байту.
Битовые поля обычно применяются в низкоуровневом программировании.
Объявление битовых полей
Элементом структуры может быть битовое поле, обеспечивающее доступ к отдельным битам памяти. Вне структур или объединений битовые поля объявлять нельзя. Нельзя также организовывать массивы битовых полей и нельзя применять к полям операцию определения адреса или получить ссылку на них.
Синтаксис объявления типа структуры с битовыми полями:
struct [ИмяСтруктуры] { Тип1 ИмяПоля1 : ШиринаПоля1 Тип2 ИмяПоля2 : ШиринаПоля2 ........................ ТипN ИмяПоляN : ШиринаПоляN } ИмяСтруктуры;
где struct – спецификатор типа;
Тип1, ... ТипN – тип поля, который может быть только int, возможно, со спецификатором unsigned или signed ;
ШиринаПоля (длина) – целое неотрицательное десятичное число, значение которого обычно (в зависимости от реализации компилятора) не должно превышать длины машинного слова.
Например:
struct { int c1 : 4; int c2 : 12; } ab;
Битовые поля длиной 1 должны объявляться как unsigned, поскольку 1 бит не может иметь знака. Битовые поля могут иметь длину от 1 до 16 бит для 16-битных сред и от 1 до 32 бит для 32-битных сред.
Разрешается поле без имени (для этого надо указать только двоеточие и ширину), с помощью которого в структуру вводятся неиспользуемые биты (промежуток между значимыми полями). Нулевая ширина поля вводится, когда необходимо, чтобы следующее в данной структуре поле разместилось с начала очередного машинного слова.
Например, если нам нужны только биты cts и dsr, то можно объявить структуру status_type следующим образом:
struct status_type { unsigned : 4; unsigned cts :1; unsigned dsr :4; } status;
В структуре можно смешивать "обычные" элементы с битовыми полями.
Например:
struct emp { struct addr address; float pay; unsigned lay_off: 1; //работает или нет unsigned hourly: 1;//почасовая оплата или оклад unsigned deductions : 3; //удержание налога };
Эта структура определяет запись по каждому служащему, в которой используется только один байт для хранения трех элементов информации: статус служащего, характер оплаты его труда и налоговая ставка. Без использования битовых полей для хранения этой информации пришлось бы занять несколько байтов.
Вместо служебного слова struct можно употреблять union. В этом случае определяется объединение с битовыми полями. Битовые поля в объединениях используются для доступа к нужным битам того или иного объекта, входящего в объединение.
Пример 1. В программе объединение позволяет сформировать код символа 'D' (равный 68):
#include "stdafx.h" #include <iostream> using namespace std; union { char simb; struct { int x:5; int y:3; } hh; } cod; int _tmain(int argc, _TCHAR* argv[]) { cod.hh.x = 4; cod.hh.y = 2; cout << cod.simb; // выводит на экран символ 'D' system("pause"); return 0; }
Доступ к элементам структур с битовыми полями
Для обращения к битовым полям используются те же конструкции, что и для обращения к обычным элементам структур:
ИмяСтруктуры.ИмяПоля (* УказательНаСтруктуру). ИмяПоля УказательНаСтруктуру -> ИмяПоля
Например, для структуры xx с битовыми полями:
struct { int a : 10; int b : 14; } xx;
правомочны следующие операторы:
xx.a=1; xx.b=48; xx.a=xx.b=0;