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’ };// ошибка