Объединения разнотипных данных.
Со структурами в «близком родстве» находятся объединения, которые вводятся с помощью служебного слова union. Чтобы пояснить степень родства объединений со структурами, рассмотрим определение структуры STR:
struct {
long L;
int i1,i2;
char c[4] ;
} STR;
Каждый элемент структуры имеет свое собственное место в памяти и размещаются эти элементы последовательно. В ниже приведенной программе опрелена структура STR и выведены значения адресов ее элементов:
// Prim8_6.cpp : Размещение в памяти элементов структуры.
#include<iostream.h>
void main ()
{
struct {
long L;
int i1,i2;
char c[4];
} STR={10L,20,30, {‘a’,’b’,’c’,’d’}};
cout << "\n sizeof (STR)=" sizeof (STR) << hex;
cout << "n&STR.L= " << &STR.L;
cout << "n&STR.i1= " << &STR.i1;
cout << "n&STR.i2= " << &STR.i2;
cout << "n&STR.c= " << &STR.c;
}
Результат выполнения программы:
sizeof (STR)=12
&STR.L= 0x8d800ff4
&STR.i1= 0x8d800ff8
&STR.i2= 0x8d800ffa
&STR.c= 0x8d800ffc
Определим очень похожее внешне на структуру STR объединение UNI:
union {
long L;
int i1,i2;
char c[4];
} UNI;
Количество элементов в объединении с именем UNI и их типы совпадают с количеством и типом элементов в структуре STR. Но существует одно очень важное отличие- все элементы объединения имеют один и тот же начальный адрес.
Следующая программа подтверждает сказанное:
//Prim8_7.cpp : размещение в памяти объединения.
#include<iostream.h>
void main ()
{
union{
long L;
int i1,i2;
char c[4];
} UNI={10L}
cout << "\n sizeof (UNI)=" << sizeof (UNI) << hex;
cout << "\n &UNI.L= " << &UNI.L;
cout << "\n &UNI.i1" << &UNI.i1;
cout << "\n &UNI.i2" << &UNI.i2;
cout << "\n &UNI.c " << &UNI.c;
cout << "\n sizeof (UNI.i1)= " << sizeof (UNI.i1) ;
cout << "\n sizeof (UNI.L)= " << sizeof (UNI.L) ;
}
Результат выполнения программы:
sizeof (UNI)=4
&UNI.L=0x8d7d0ffc
&UNI.i1=0x8d7d0ffc
&UNI.i2=0x8d7d0ffc
&UNI.c=0x8d7d0ffc
sizeof (UNI.i1)=2
sizeof (UNI.L)= 4
Как подтверждают результаты выполнения программы все элементы объединения UNI имеют один начальный адрес. Размеры элементов соответствуют их типам, а размер объединения определяется размером его максимального элемента.
Итак, объединение можно рассматривать как структуру, все элементы которой при размещении в памяти имеют нулевое смещение от начала. Тем самым все элементы объединения размещаются в одном и том же участке памяти.
Как и для структур, для объединения может быть введен программистом произвольный тип, определяющий «внутреннее строение» всех объединений, относящихся к этому типу. Если для структур английский термин tag мы заменили на структурный тип, то для union type можно говорить об объединяющем типе. Поэтому будем говорить о типе объединения:
union имя_объединяющего_типа
{элементы объединения};
Пример объединяющего типа :
union mixture {
double d;
long E[2];
int k[4];
};
Введя тип объединения, можно определять конкретные объединения, их массивы, а также указатели и ссылки на объединения:
mixture mA,mB[4]; // объединение и массив объединений
mixture *pmix; // указатель на объединение
mixture &rmix=mA; // ссылка на объединение
Заносить значения в участок памяти, выделенный для объединения, можно с помощью любого из его элементов. То же самое справедливо и относительно доступа к содержащему участку памяти, выделенному для объединения. Если бы элементы объединения имели одинаковую длину и один тип, а отличались только именами, то использование объединений было бы подобно применению ссылок. Просто первый участок памяти имел бы несколько различных имен. Основное достоинство объединения- возможность разных трактовок одного и того же содержимого участка памяти.
Если включить в объединение символьный массив такой же длины, что и другие элементы объединения, то получим возможность доступа к отдельным байтам внутреннего представления объединения.
Итак, основное назначение объединений – обеспечить возможность доступа к одному и тому же участку памяти с помощью объектов разных типов.
При определении объединений без явного указания имени объединяющего типа разрешено не вводить даже имени объединения. В этом случае создается анонимное, или безымянное объединение.
Перечисления
В языке С++ существует конструкция enum, называемая перечислением.
enum имя {
компонента_1,
. . . . . . . . . . . . .,
компонента_n
};
где имя – имя перечисления;
компонента – некоторое уникальное в пределах определения имя или комбинация «имя=значение», где «значение»- константное целое выражение.
Перечисление enum действует следующим образом. Первой компоненте, если для нее не указано значение, ставится в соответствие число 0, если значение указано, то это значение. Каждый последующий элемент получит значение предыдущего, увеличенный на 1, если для него значение не указано явно. Таким образом, дни недели объявляются так:
enum DAYS {Monday, Tuesday, Wednesday , . . . , Sunday};
Можно объявить переменную типа enum:
enum DAYS v;
Пример:
v=Tuesday;
v++; // v=Wednesday
v-=2; // v=Monday
то есть с перечислениями можно работать как с целыми типами. Целым типам можно присваивать перечисляемые константы, то есть любой перечисляемый тип- это тип int.
Дата добавления: 2017-01-29; просмотров: 631;