• Цвет фона выбирается из следующей палитры: черный, красный, зеленый, желтый, синий, пурпурный, голубой и белый.
• Рамка может быть скрыта или отображена.
• Цвет рамки выбирается из той же палитры, что и цвет фона.
• Для рамки применяются три стиля линии: сплошная, пунктирная и штриховая.
Для каждого свойства можно было бы использовать отдельную переменную или полноразмерный член структуры, но это привело бы к напрасному расходу битов. Например, для указания прозрачности или непрозрачности окна достаточно одного бита. То же самое можно сказать о свойстве отображения или сокрытия рамки. Восемь возможных значений цвета могут быть представлены 3-битовым элементом, а 2-битового элемента более чем достаточно для представления трех возможных стилей рамки. Таким образом, для представления всех пяти свойств достаточно 10 битов.
Один из вариантов представления информации предусматривает применение заполнителей, чтобы поместить связанную с фоном окна информацию в один байт, а связанную с рамкой — во второй. Это реализовано в следующем объявлении struct box_props:
struct box_props {
bool opaque : 1;
unsigned int fill_color : 3; unsigned int : 4;
bool show_border : 1;
unsigned int border_color : 3; unsigned int border_style : 2; unsigned int : 2;
};
В результате использования заполнителей размер структуры увеличивается до 16 битов. Без них было бы достаточно 10 битов. Однако имейте в виду, что в С для структур с битовыми полями в качестве базовой единицы размещения применяется тин unsigned int. Поэтому, даже если структура содержит единственный элемент, которым является однобитовое поле, структура будет иметь такой же размер, как у типа unsigned int, что в нашей системе составляет 32 бита. Кроме того, в этом коде предполагается, что тип _Bool из С99 доступен и в заголовочном файле stdbool.h ему назначен псевдоним bool.
Для члена opaque можно использовать значение 1 для указания непрозрачности окна и значение 0 — для прозрачности. То же самое применимо к члену show_border.
Манипулирование битами 645
Для цветов можно использовать простое представление RGB (красный, зеленый, синий). Это основные цвета для смешивания спектра. В мониторе для воспроизведения различных цветов применяется смешанное свечение красных, зеленых и синих пикселей. В ранних моделях мониторов каждый пиксель мог иметь только включенное или выключенное состояние, поэтому для представления интенсивности каждой из трех составляющих было достаточно одного бита. Обычно левый бит представлял интенсивность синего, средний — интенсивность зеленого, а правый — красного цвета В табл. 15.3 показаны восемь возможных комбинаций. Они могут служить значениями для членов f ill_color и border color. Наконец, значения 0, 1 и 2 могут представлять сплошной, пунктирный и штриховой тип линий, определяемый членом border style.
Таблица 15.3. Простое представление цветов

В листинге 15.3 структура box_props используется в простом примере. Директивы #define применяются для создания символических констант, представляющих возможные значения членов. Обратите внимание, что основные цвета представлены включением единственного бита. Остальные цвета могут представляться комбинациями основных цветов. Например, пурпурный цвет создается включением битов синего и красного цветов, поэтому его можно записать как комбинацию BLUE I RED.
Листинг 15.3. Программа fields.с

646 Глава 15

Вот вывод, полученный из программы:
Исходные настройки окна:
Окно непрозрачно.
Цвет фона желтый.
Рамка отображается.
Цвет рамки зеленый.
Стиль рамки штриховой.
Измененные настройки окна:
Окно прозрачно.
Цвет фона белый.
Рамка отображается.
Цвет рамки пурпурный.
Стиль рамки сплошной.
Манипулирование битами 647
Отметим несколько моментов. Прежде всего, структуру битовых полей можно инициализировать с использованием обычного для структур синтаксиса:
struct box_props box = {YES, YELLOW , YES, GREEN, DASHED};
Аналогично можно присваивать значения элементам битовых полей:
box. fill_color = WHITE;
Кроме того, член битового поля может служить выражением в операторе switch. Он даже может выступать в качестве индекса массива:
Читать дальше