
Поля битов в структурах
Поле битов - это элемент (поле) структуры, определенный как некоторое число бит, обычно меньшее, чем число бит в целом числе, предназначенные для экономного размещения в памяти данных небольшого диапазона.
Пример:
struct bufer {
unsigned int flag1 : 10;
unsigned int flga2 : 6;
};
Данная структура описывает 10-битовое поле для flag1, которое для вычислений преобразуется в значение типа unsigned int, и 6-битовое поле для flag2, которое обрабатывается как значение типа unsigned int.
Объединения
Объединение - это тип переменной, которая может иметь любой тип из некоторого множества типов, хранимых в одном адресном пространстве.
Формат описания объединения, аналогичен описанию структурного типа данных:
union имя_объединения {
Описания_элементов
};
Пример:
union bigword
{
long big_long;
char *big_char [4];
};
Данные типа union bigword занимают память, необходимую для размещения наибольшего из своих элементов, и выравниваются в памяти к границе, удовлетворяющей ограничениям по адресации как для типа long, так и для типа char *[4].
Пример:
union hold
{
int digit;
double bigfloat;
char letter;
};
Объединение может хранить значение типа или int, или double, или char.
Пример определения трех переменных объединения:
union hold fit; // переменная fit объединения типа hold
union hold save[10]; // массив из 10 переменных объединения
union hold *ptr; // указатель на переменную типа hold
Первое объявление создает единственную переменную fit. Компилятор выделяет пространство памяти, достаточное для того, чтобы хранить наибольшую из описанных вариантов, а именно тип double, который требует для себя обычно 8 байт.
Второе объявление save[10] создает массив с 10 элементами, каждый из которых имеет размер в 8 байт.
Третье объявление создает указатель, который может содержать адрес объединения hold.
Инициализация объединения
Обращение к полям объединения осуществляется аналогично полям структуры, например:
union hold valA;// создали переменную valA по шаблону union hold
valA.letter = 'R';
union hold valB = valА;// инициализация одного объединения другим
union hold valC = {88};// инициализация числового элемента
Рассмотрим варианты использования объединения:
union hold fit;
fit.digit = 23; // Число 23 хранится в переменной fit, 2 байта
fit.bigf = 6.78; // Число 23 затерто, хранится 6.78, 8 байтов
fit.letter = 'h';// Число 6.78 затерто, хранится символ h,1 байт
Операция «точки» показывает, какой тип данных используется в текущий момент. За один раз запоминается только одно значение. Нельзя одновременно хранить значение типа char и значение типа int, даже если для этого имеется достаточно пространства (памяти для 8 байт).
При инициализации полей объединения вместо операции точки можно использовать операцию стрелки, если используется указатель на объединение. В частности, для рассмотренных примеров:
int x;
ptr = &fit;
x = ptr->digit;
Замечание.
1) Фактически объединение является структурой, в которой все элементы имеют нулевое смещение от ее начала. Она имеет достаточную длину, чтобы в нее поместился самый длинный элемент, и при этом выравнивание выполняется правильно для всех типов данных в объединении.
2) Над объединениями разрешено выполнять те же операции, что и над структурами: присваивать или копировать как единое целое, брать адрес и обращаться к отдельным элементам.
3) Элементом объединения может быть структура.