Битовые поля

Размещение структурных переменных в памяти

Массивы структур

Структурный тип "struct ID_структуры", как правило, используют для декларации массивов, элементами которых являются структурные переменные. Это позволяет создавать программы, оперирующие с "примитивными базами данных". Например:

struct person spisok[100]; // spisok - массив структур

Или можно записать так:

struct person {

char fio[40];

int day, month, year;

} spisok[100];

В данном случае обращение к полю day i -той записи может быть выполнено, например, так:

spisok[i].day=22;

Элементы структур в общем случае размещаются в памяти последо­ва­тельно с учетом выравнивания начальных адресов полей.

Выравнивание (align) означает, что компилятор выбирает адреса переменных (в т.ч. полей структуры) так, чтобы они были кратны некоторой величине. Эта величина определяется типом переменной и особенностями адресации данных этого типа на аппаратном уровне (чаще всего она равна 2). Часто выравнивание не обязательно, но при этом скорость обращения к объекту может снижаться. Если выравнивание производится, компилятор может быть вынужден добавить между полями структуры пустые байты, и тогда размер структуры (определяемый с помощью sizeof) будет превышать сумму размеров ее полей.

Наряду с "обычными" типами, допустимыми и для "отдельных" переменных, поля структуры могут иметь особый целочисленный тип, допустимый только для них - битовые поля.

Битовые поля содержат заданное количество бит, необязательно кратное байту, но не превосходящее количество бит в типе int (в С++ Builder'е - 32). Они могут быть знаковыми (по умолчанию - signed) либо беззнаковыми (unsigned), причем слово signed обычно опускается. В знаковых полях старший бит означает знак числа, аналогично всем целочисленным типам (см. выше тему "Кодирование целых чисел").

Объявление знакового битового поля имеет вид:

int a: размер;

а беззнакового битового поля:

unsigned b: размер;

где размер - количество бит в поле.

Пример:

struct T {

int a:5, b:4;

unsigned c:5;

float d;

unsigned e:2, f:5;

};

Выравнивание, рассмотренное выше, выполняется не для отдельных битовых полей, а только для совокупностей подряд идущих битовых полей (именно поэтому битовые поля применяются лишь в составе структур). Так, в приведенном примере битовые поля a, b и c располагаются в памяти подряд, занимая вместе одну двухбайтовую ячейку, как показано на схеме:

№ бит 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Поля   c b a

Как видно из рисунка, поля располагаются в ячейке от младших бит к старшим; при этом в примере последние 2 бита остались неиспользованными.

Аналогично, поля e и f занимают однобайтовую ячейку:

№ бит   6 5 4 3 2 1 0
Поля   f e

Если размер объединенной ячейки превысил бы размер типа int, компилятор может разбить ее на отдельные меньшие ячейки.

Общая схема распределения памяти под структуру типа Т:

№ байт 0 1 2 3 4 5  
Поля a,b,c d e,f

Заметим, что адрес отдельного битового поля получить невозможно.

Битовые поля позволяют:

1) уменьшить размер памяти, отводимой под переменную. В примере поля a,b,c,e,f в сумме заняли лишь 3 байта;

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: