Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
учебное пособие ОАиП.doc
Скачиваний:
11
Добавлен:
25.04.2019
Размер:
2.63 Mб
Скачать

Поля бит

Существует несколько разновидностей структур. Одна из них - это поля бит. Поле представляет собой последовательность соседних двоичных разрядов (бит) внутри одного целого значения. Каждое поле может иметь тип unsigned int или signed int и размещается в машинном слове целиком, а вся группа полей может выходить за пределы машинного слова. Поле бит – особый тип структуры определяющий какую длину имеет каждый ее элемент. Общий вид объявления полей бит имеет вид:

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

{ тип имя 1: длина;

. . .

тип имя n : длина;

};

Наиболее распространенный подход к использованию полей можно показать на примере объявления следующей структуры:

struct pole

{ int p1:1;

unsigned p2:2;

int:6;

int p3:4;

} pl;

Объявление такого вида обеспечивает размещение стуктуры (полей бит) в памяти следующим образом. В полях типа signed крайний левый бит является знаковым. Таким образом, поле signed int p:1 может быть использовано для хранения значений -1 и 0, так как любое не нулевое значение поля p будет интерпретироваться как -1. Поле signed int p:2, в отличие от int p:1, может принимать три значения -1,0,1. В объявлении структуры имеется еще два поля (int:6; int p3:4). Первое указывает, что структура содержит 6 неиспользуемых бит, второе предназначено для чисел в диапазоне от –7 до 7.

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

Все особенности, связанные с использованием полей, например: может ли поле байт перейти границу слова, зависят от аппаратной реализации.

При определенном удобстве работа с полями может повлечь некоторые трудности. Они связаны, например, с тем, что на одних машинах поля размещаются слева направо, на других - справа налево. Это в свою очередь влечет некоторые трудности при перенесении программ. Поля не могут быть массивами и не имеют адресов и, следовательно, операция & к ним не применима.

Объединения

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

Формат объявления объединения имеет следующий вид:

union { описание элемента 1;

...

описание элемента n; };

Спецификация доступа к элементам объединения, как и у полей бит, полностью соответствует тому, как это осуществляется у обычных структур:

имя_объединения . имя поля объединения;

или при работе с указателями:

имя_указателя _на_объединение-> имя_поля_объединения;

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

union un_type

{ int i; // пример объявления

double d; // шаблона объединения

char c;

};

un_type un; // переменная типа объединения

un_type un_mas[6]; // массив из шести элементов

un_type *pt; // указатель на переменную типа un_type

Первое описание приводит к выделению памяти под одну переменную un. При этом компилятор выделяет достаточно памяти для размещения max из переменных описанных в шаблоне un_type, т.е. 8 байт (тип double). Для массива un_mas[6] выделяется 6х8 байт памяти. Механизм использования объединения может быть рассмотрен на следующем примере:

un.i=14; // 14 записывается в переменную un; исп-ся 2 байта

un.d=3.4; // 14 стирается, 3.4 записывается; исп-ся 8 байтов

un.c=‘k’; // 3,4 стирается, записывается k; используется 1 байт

В каждый момент времени запоминается только одно значение; нельзя записать char и int одновременно в одно объединение даже, если для этого достаточно памяти. Приведенный ниже фрагмент демонстрирует ошибочное использование полей объединения:

un.d=2.4;

un.i=14;

f=5.2*un.d; // ошибка

Ошибка заключается в том, что в момент использования un.d его значение 2.4 затерто оператором un.i=14;

Как отмечалось выше, с объединениями можно использовать операцию -> аналогично, как это делалось со структурами.

pt=&un;

f=pt->d; // аналогично f=un.d

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