Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект С++ (Часть 2).doc
Скачиваний:
16
Добавлен:
10.09.2019
Размер:
816.64 Кб
Скачать

Битовые поля структур

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

struct Date

{

unsigned WeekDay : 3; // 0..7 (3 бита)

unsigned MonthDay : 5; // 0..31 (5 бит)

unsigned Month : 4; // 0..12 (4 бита)

unsigned Year : 12; // 0..4048 (12 бит)

} D1;

Под переменную D1 в памяти будет отведено всего 4 байта:

0 … 2

3 … 7

8 … 11

12 … 23

24 … 31

WeekDay

MonthDay

Month

Year

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

3 бита

5 бит

4 бита

12 бит

8 бит

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

Для хранения логического значения под битовое поле отводится 1 бит:

struct Flags

{

bool b1: 1;

bool b2: 1;

bool b3: 1;

bool b4: 1;

bool b5: 1;

bool b6: 1;

bool b7: 1;

bool b8: 1;

} Fl;

Под переменную Fl в памяти будет отведен 1 байт. Таким образом, в одном байте памяти можно разместить 8 логических значений.

Обращение к битовым полям осуществляется так же, как и к обычным полям структур:

D1.WeekDay = 4;

D1.MontthDay = 25;

D1.Month = 9;

D1.Year = 2004;

В одной структуре можно совместно использовать и обычные и битовые поля.

10.2. Объединения Обычные объединения

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

union t_num{

int i;

double d;

};

Здесь описан новый тип данных с именем t_num, представляющий собой объединение двух членов (полей, элементов), каждый из которых задан типом данных и именем. Члены объединений могут быть любых типов, а их количество – любым.

Для работы с объединением следует определить соответствующие переменные:

t_num A, B; // Определены две переменные А и В

Создание переменных модно совместить с описанием объединения:

union t_num{

int i;

double d;

} A, B; // Описан тип данных t_num и определены две переменные А и В

Обращение к полям объединения осуществляется так же, как и к элементам структуры – с использованием оператора “точка”:

A.i = 13;

B.d = 3.14;

cout << A.i + B.d;

Если обращение к полям объединения осуществляется через указатель, то необходимо использовать оператор “стрелка”:

t_num *p = &A; // Указатель на объединение р инициализирован адресом переменной А

p -> d = 234.33; // Полю d переменной А присвоено новое значение

Передача объединений в качестве аргументов функций осуществляется точно так же, как и для структур.

В памяти члены объединения “накрывают” друг друга (располагаются по одному адресу):

Если вывести на экран адреса переменной А и полей i и d

cout << &A << " " << &A.i << " " << &A.d << endl;

то будут выведены три одинаковых адреса.

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

Например, необходимо написать функцию обеспечивающую перестановку младшего и старшего байта короткого целого:

short Swap ( short I)

{

union t_U {

short i;

char c [2];

} u;

u.i = I;

char ch = u.c [0];

u.c [0] = u.c [1];

u.c [1] = ch;

return u.i;

}

cout << Swap (1234) << endl; // На экране -11772

Переменная u из этой функции интерпретируется в памяти так: