Структуры могут содержать битовые поля – последовательности двоичных разрядов внутри одного целого значения. Язык C++ позволяет использовать любой целый тип . Будет он знаковым или беззнаковым, зависит от реализации компилятора, так же как и порядок размещения битовых полей в машинном слове. Именно поэтому битовые поля имеют имена, для обеспечения независимости от машинной реализации.
struct kilo
{
int a:2;
unsigned b:3;
int :5 // не используется
int c:1:
unsigned d:5;
};
d
c
не используется
b
a
Для битового поля можно явно определить тип signed или unsigned. В битовом поле типа signed крайний левый бит является знаковым. Такое поле шириной в 1 бит может хранить значения только 0 или –1.
Битовое поле без имени просто резервирует указанное число разрядов. Битовое поле без имени с нулевым размером указывает, что следующее битовое поле начинается на границе машинного слова.
Доступ к битовому полю производится также как к компоненту структуры.
kilo ssc;
ssc.a = 1;
Битовые поля используются для упаковки значений нескольких переменных в одно машинное слово с целью экономии памяти, отводимой под данные, но это увеличивает размер исполняемого кода для доступа к этим данным и снижает производительность программы.
Битовые поля позволяют также выполнять преобразование данных в другие форматы.
Битовые поля не могут быть массивами и не имеют адресов, поэтому к ним нельзя применить операцию получения адреса &, на них не может быть указателей и ссылок. Можно получить адрес структуры, содержащей битовые поля.
Объединение – это некоторая переменная, которая может хранить в разное время объекты различных типа и размера. Такая переменная имеет размер, достаточный для размещения наибольшего из своих полей. Объединения объявляются при помощи служебного слова union.
union romeo
{
int ir;
double fr;
char ch;
};
Объединения могут иметь (и часто имеют) имя, которое становится идентификатором типа, в противном случае объединения являются анонимными. К полям анонимных объединений можно обращаться так же, как если бы они были самостоятельными переменными. Глобальные анонимные объединения должны быть объявлены как статические (?).
romeo zulu;
//…
zulu.ir = 15; // обращение к полю (не инициализация)
Статические объединения могут быть инициализированы значениями в фигурных скобках {}, причём инициализировано может быть лишь первое поле.
romeo zulu = {15}; // инициализация
romeo zulu = {‘F’}; // неправильно, т.к. первое поле имеет тип int, а не char
Статические массивы объединений также могут быть инициализированы
romeo x_ray[ ] = {3,5,7};
Могут существовать указатели
romeo *mike;
и ссылки на объединения:
romeo& foxtrot = zulu;
Доступ к объединениям через ссылку
foxtrot.fr = …
через указатель
(*mike).ir = … или mike–>ch = …
Если поля объединения имеют одинаковый тип и длину, отличаясь только именами, то использование объединения подобно применению ссылки.
Основное достоинство объединений – возможность разных трактовок одного и того же содержимого некоторого участка памяти, т.е. доступ к одному и тому же участку памяти с помощью объектов разных типов:
union { // Безымянное объединение
float F;
unsigned long K; } FK;
FK.F = 3.141593;
FK.K ~ 1078530012
Битовые поля могут входить в состав объединений как структуры: