Битовые поля
Цель лекции: изучить понятие, объявление и размещение в памяти битовых полей, доступ к битовым полям структуры или объединения и научиться решать задачи с использованием битовых полей на языке 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;