Поля битов

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

struct {Тип Идентификатор 1: ДдлинаПоля 1; Тип Идентификатор 2: ДлинаПоля 2; }

Тип – это char, unsigned char, int, unsigned int. ДлинаПоля задается целым выражением или константой. Эта константа определяет число битов, отведенное соответствующему полю. Целочисленные компоненты типа signed или unsigned можно объявлять битовыми полями шириной от 1 до 16 бит. Поле нулевой длины обозначает выравнивание на границу следующего слова.

Пример:

struct { unsigned a1: 1;unsigned a2: 2;unsigned a3: 5;unsigned a4: 2; } prim;

Допустимы неименованные поля (они не доступны программе, т.е. не используются); они не влияют на смысл именованных полей, но неким машинно-зависимым образом могут улучшить размещение:

struct sreg {

unsigned e: 1;

unsigned p: 3;

unsigned: 1; // неиспользуемое

unsigned m: 2;

unsigned: 4: // неиспользуемое

int a: 1;

int k: 1;

unsigned n: 2;}

создает следующее распределение памяти

где х – не используемые биты.

Этот пример также иллюстрирует другое основное применение полей: именовать части внешне предписанного размещения.

Поле должно быть целого типа и используется как другие целые, за исключением того, что невозможно взять адрес поля. Целочисленные поля хранятся в виде дополнения до двух, причем крайний левый бит помещается в MSB(наиболее значащий). Для битового поля типа Int (например, signed) MSB интерпретируется как знаковый бит. Битовое поле шириной 2, содержащее 11, будет следовательно интерпретироваться для unsigned как 3, а для int как –1. В предыдущем примере допустимое выражение sreg.n=6 поместит в sreg.n двоичное 10=-2, не выдавая каких-либо предупреждений. Поле k типа int шириной 1 может содержать только значения 0 и –1, т.к. битовый шаблон 1 будет считаться знаковым и интерпретироваться в –1.

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

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

Битовые поля могут быть объявлены только в структурах, объединениях и классах.

Пример:

#include <stdio.h>

union

{

long int IntVal;

float FloatVal;

struct

{

int bit0: 1;

int bit1: 1;

int bit2: 1;

int bit3: 1;

int bit4: 1;

int bit5: 1;

int bit6: 1;

int bit7: 1;

int bit8: 1;

int bit9: 1;

int bit10: 1;

int bit11: 1;

int bit12: 1;

int bit13: 1;

int bit14: 1;

int bit15: 1;

int bit16: 1;

int bit17: 1;

int bit18: 1;

int bit19: 1;

int bit20: 1;

int bit21: 1;

int bit22: 1;

int bit23: 1;

int bit24: 1;

int bit25: 1;

int bit26: 1;

int bit27: 1;

int bit28: 1;

int bit29: 1;

int bit30: 1;

int bit31: 1;

} BitField;

} MyUnion;

void main ()

{

MyUnion.BitField.bit31 = 0;

MyUnion.BitField.bit30 = 1;

MyUnion.BitField.bit29 = 0;

MyUnion.BitField.bit28 = 0;

MyUnion.BitField.bit27 = 0;

MyUnion.BitField.bit26 = 0;

MyUnion.BitField.bit25 = 1;

MyUnion.BitField.bit24 = 1;

MyUnion.BitField.bit23 = 0;

MyUnion.BitField.bit22 = 0;

MyUnion.BitField.bit21 = 1;

MyUnion.BitField.bit20 = 1;

MyUnion.BitField.bit19 = 0;

MyUnion.BitField.bit18 = 0;

MyUnion.BitField.bit17 = 1;

MyUnion.BitField.bit16 = 0;

MyUnion.BitField.bit15 = 0;

MyUnion.BitField.bit14 = 0;

MyUnion.BitField.bit13 = 1;

MyUnion.BitField.bit12 = 0;

MyUnion.BitField.bit11 = 0;

MyUnion.BitField.bit10 = 0;

MyUnion.BitField.bit9 = 0;

MyUnion.BitField.bit8 = 0;

MyUnion.BitField.bit7 = 0;

MyUnion.BitField.bit6 = 0;

MyUnion.BitField.bit5 = 0;

MyUnion.BitField.bit4 = 0;

MyUnion.BitField.bit3 = 0;

MyUnion.BitField.bit2 = 0;

MyUnion.BitField.bit1 = 0;

MyUnion.BitField.bit0 = 0;

long int k;

k= MyUnion.IntVal>>4;

printf("%f\n", MyUnion.FloatVal);

printf("%lx\n", MyUnion.IntVal);

printf("%lx\n", k);

}


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



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