2. Структуры и объединения разнотипных элементов в С++

Из основных типов языка С++ пользователь может конструировать производные типы, например структуры и объединения. Структуры и объединения отнесены к структурированным типам.

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

struct card {char *author;  //  Ф.И.О.  автора книги

char *title;

char *city;

char *firm;

int year;

int pages;

};

Такое определение вводит новый производный тип, который называется структурным типом. В данном примере у этого структурного типа есть конкретное имя  card.

В соответствии с синтаксисом языка определение структурного типа начинается со служебного слова struct, вслед за которым помещается выбранное пользователем имя типа. Описание элементов, входящих в структуру, помещаются в фигурные скобки, вслед за которыми ставится точка с запятой. Элементы структуры могут быть как базовых, так и производных типов. Например, в структурах типа card будут элементы базового типа int и производного типа char * .

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

сard rec1, rec2, rec3;

Здесь определены три структуры (три объекта) с именами rec1, rec2, rec3. Каждая из этих структур содержит в качестве элементов свои собственные данные:

char *title;

char *city;

состав, которых определяет структурный тип с именем card.

.h

using namespace std;

struct Pointe

{

                int x, y;

                Pointe(int xx, int yy) : x(xx), y(yy) {};

                Pointe operator + (Pointe &other);

                void display()

                {

                               cout << x << " and " << y << "\n";

                }

};

 

Pointe Pointe::operator + (Pointe &other)

{

                return Pointe(x + other.x, y + other.y);

}

 

.cpp

#include "c_console.h"

 

int _tmain(int argc, _TCHAR* argv[])

{

                Pointe p1(1, 2);

                Pointe p2(10, 20);

                Pointe p3(0, 0);

                p3 = p1 + p2;

                p3.display();

                _getch();

                return 0;

}

 

Объединения вводятся с помощью служебного слова union. Пусть дана структура

struct { long L; int i1, i2; char c[4]; } STR;

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

union { long L ; int i1, i2; char c[4]; } UNI;

Количество элементов в объединении с именем UNI и их типы совпадают с количеством и типами элементов в структуре STR. Но существует одно очень важное отличие - все элементы объединения имеют один и тот же начальный адрес размещения в памяти. То есть объединение можно рассматривать как структуру, все элементы которой при размещении в памяти имеют нулевое смещение от начала. Тем самым все элементы объединения размещаются в одном и том же участке памяти. Размер участка памяти, выделяемого для объединения, определяется максимальной длиной его элементов. Как и для структур, для объединений может быть введен программистом производный тип, определяющий "внутреннее строение" всех объединений, относящихся к этому типу.

union имя_объединяющего_типа {элементы_объединения};

Пример объединяющего типа:

union mixture { double d; long E[2]; int K[4]; };

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

mixture mA, mB[4]; // Объединение и массив объединений

mixture *pmix; // Указатель на объединение

mixture& rmix = mA; // Ссылка на объединение

Для обращения к элементу объединения можно использовать либо уточненное имя имя_объединения.имя_элемента, либо конструкцию, включающую указатель:

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

(*указатель_на_объединение).имя_элемента;

либо конструкцию, включающую ссылку ссылка_на_объединение. имя_элемента

mA.d = 64.8;

mB[2]. E[1] = 10L;

pmix = &mB[0];

pmix -> E[0] = 66;

cin >> ( *pmix ).K[1];

cin >> rmix. E[0];

Заносить значения в участок памяти, выделенный для объединения, можно с помощью любого из его элементов. То же самое справедливо и относительно доступа к содержимому участка памяти, выделенного для объединения.  Основное достоинство объединения - возможность разных трактовок одного и того же содержимого (кода) участка памяти. Например, введя объединение union { float F; unsigned long K; } FK; можно занести в участок памяти, выделенный для объединения FK, вещественное число: FK.F = 3.141593; а затем рассматривать код его внутреннего представления как некоторое беззнаковое длинное целое: cout << FK.K; (в данном случае будет выведено 10785330012).

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

union compound { long LONG; int INT[2]; char CHAR[4]; };

compound mix1 = { 11111111 }; // правильно

compound mix2 = { ‘a’, ‘b’, ‘c’, ‘d’ };// ошибка

Hosted by uCoz