Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курс лекций по программированию и алгоритмизаци...doc
Скачиваний:
31
Добавлен:
05.09.2019
Размер:
2.24 Mб
Скачать

4.5.3. Поля битов

В отличие от других языков программирования Си обеспечивает доступ к одному или нескольким битам в байте или слове. Если переменные принимают только два значения (например, логические) можно использовать один бит. Такие переменные называют флагами.

Доступ к биту обеспечивают поля битов (bit fields) – это специальный тип членов структуры, в котором определено, из скольких битов состоит каждый элемент. Полем считается последовательность соседних двоичных разрядов в числе типа int или unsigned (signed). Оно объявляется как элемент структуры.

Основная форма объявления структуры битовых полей

struct имя структуры

 тип имя 1: ширина;

тип имя : ширина;

;

где ширина – целое число от одного до 16; тип – int или unsigned. Имя может отсутствовать, тогда отведенные биты не используются (пропускаются). Длина структуры всегда кратна восьми.

Пример 1. Для переменной obj будет выделено восемь бит, но используется только первый.

struct onebit

 unsigned b: 1;

obj;

Пример 2.

struct М // значения диапазонов полей

int а:4; // а-8, 7

int b:1; // b- 1, 0

unsigned с:5; // с0,31

int :2; // пусто

int d :2; // d-2,1

unsigned е :2 // е0,3

Расположение полей в структуре М из 16 бит получится следующее

А

b

с

не используется

d

е

0 … 3

4

5 … 9

10 11

12 13

14 15

Операции для полей битов такие же, как и для структур:

Присваивание. Пусть struct М byte; то byte.а=3;

byte.b=0;

Доступ к полю (точка) byte.с=30;

Не допускаются массивы полей битов, указатели на поля битов и функции, возвращающие поля битов. К битовым полям не может применяться операция «&» (адрес).

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

В структуре могут быть смешаны обычные переменные и поля битов. Поля битов не могут располагаться на пересечении границ объявленных для них типов (они располагаются в оставшемся пространстве предыдущего поля или начиная с новой целой границы).

Безымянное поле используется только как заполнитель. Для принудительного выравнивания к границе следующего целого числа используется специальный размер

struct  int f1:1

int : 2;

int f2:1;

:; stb.f3 заполняется в следующем int.

int f3:1 ;

 stb;

4.5.4. Объединения Используются для хранения значений различных типов в одной и той же области памяти, но не одновременно.

Объединение – это структура, все элементы которой имеют нулевое смещение, а сама структура достаточно велика, чтобы вместить самый большой элемент, и выровнена так, чтобы можно было работать с любым элементом. Объявляется объединение, как и структура, но с ключевым словом union. Это объявление не задает какую- либо переменную, а определяет лишь шаблон.

union имя структуры тип 1 имя 1;

тип 2 имя 2;

тип  имя  ;

Для объявления переменной записывается:

union <имя структуры> <имя переменной>;

В объединении не допускаются элементы типа полей битов.

Можно объявлять переменные одновременно с заданием шаблона.

Пример:

а) union u  int i;

char c;

long l;

 a, *р ;

б) struct s  int i;

char c;

long l ;

 b;

Для переменной типа union места в памяти выделяется столько, сколько надо элементу объединения, имеющему наибольший размер в памяти. Остальные переменные будут располагаться в том же месте памяти, начиная с одного и того же адреса (с наложением).

При инициализации объединения задается значение первого элемента в соответствии с его типом. Например,

union u  char name 10

int t

 u1=Утро

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

Пример использования полей битов и объединений.

#include <stdio.h>

#include <conio.h>

struct byte

{

unsigned b1:1;

unsigned b2:1; // целое без знака

unsigned b3:1;

unsigned b4:1;

unsigned b5:1;

unsigned b6:1;

unsigned b7:1;

unsigned b8:1;

}; //Определена структура битовое поле

union bits {

char ch;

struct byte b;

} u;

void decode(union bits b); // Прототип функции

void main()

{

do { u.ch=getche();

printf(": ");

decode(u);

} while (u.ch!='q'); // цикл повторять, пока не будет

} // введен символ "q"

void decode(union bits p) // функция

{

printf("%d%d%d%d%d%d%d%d",p.b.b8,p.b.b7,p.b.b6,

p.b.b5, p.b.b4,p.b.b3,p.b.b2,p.b.b1);

printf("\n");

}