Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции_СП_2004_1_00.doc
Скачиваний:
69
Добавлен:
04.11.2018
Размер:
882.69 Кб
Скачать

6. Объединения

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

union <tag> { member-declaration list } <declarator <, ... >>;

или

union tag declarator <, declarator ... >;

Здесь union есть ключевое слово языка Си, а остальные обозначения использованы в смысле своих прежних значений. Declarator чаще всего является идентификатором переменной, возможно модифицированным с помощью квадратных скобок (для массивов объединений) или символа звездочка (для указателей на объединения). Память, выделяемая под объединения, определяется длиной наибольшего элемента в составе данного объединения. При этом все члены объединения хранятся в одной и той же области памяти с неизменным начальным адресом. Для иллюстрации использования объединений рассмотрим пример организации данных, обеспечивающих доступ к рабочим регистрам микропроцессоров Intel 8086/80286.

union REGS { struct { unsigned int ax;

unsigned int bx;

unsigned int cx;

unsigned int dx; } x;

struct { unsigned char al, ah;

unsigned char bl, bh;

unsigned char cl, ch;

unsigned char dl, dh; } h;

} regs;

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

regs.x.ax

моделирует доступ к регистру AX микропроцессора, а выражения

regs.h.al и regs.h.ah

обеспечивают соответственно доступ к младшему AL и старшему AH байтам этого регистра.

7. Перечисления

Тип данных перечисление позволяет определить набор символических имен, связав с каждым из них числовое значение целого типа. Как и при определении структур, допустимыми являются две общие формы составления описаний:

enum <tag> { enum-list } <identifier <, identifier ... >>;

или

enum tag identifier <, identifier ... >;

Здесь enum есть ключевое слово языка Си, а под enum-list понимается список разделенных запятыми идентификаторов и необязательных выражений константного типа:

identifier <= cjnstant-expression>

Каждый идентификатор в этом списке именует один элемент из множества перечисляемых значений. По умолчанию первый из них получает значение нуль, второй - значение единица и т. д. Опция

= constant-expression

входящая в enum-list, позволяет нарушить стандартное правило назначения числовых значений именам из этого списка, причем константное выражение constant-expression должно иметь тип int. Допустимым также является совпадение числовых значений различных имен в списке. Теги перечислений определяются по тем же самым правилам, что и теги структур и объединений, и могут быть использованы в сокращенной форме описания, замещая enum-list. В следующем примере определяется перечисление с именем day и объявляется переменная workday, имеющая тип перечисление:

enum day { saturday,

sunday = 0,

monday,

tuesday,

wednesday,

thursday,

friday } workday;

Значение нуль связывается с идентификатором saturday по умолчанию, а идентификатору sunday оно же присваивается явным образом. Остальные пять имен в этом списке последовательно получают значения от 1 до 5.