Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика 1.docx
Скачиваний:
11
Добавлен:
26.09.2019
Размер:
364.88 Кб
Скачать

Вложенное описание структур и объединений.

В языке C допускается многоуровневое вложенное описание структур и объединений. В ряде случаев это имеет огромное практическое значение. Например, с помощью следующего описания можно легко разбить число типа int на 4 составляющих его байта:

union unIntParts

{

int iNum;

struct

{

unsigned char Byte0;

unsigned char Byte1;

unsigned char Byte2;

unsigned char Byte3;

}Bytes;

}IntParts;

Допустим, что в программе необходимо считать и распечатать 4 байта некоторого числа x типа int по-отдельности. Осуществить это можно следующим образом:

void PrintBytes(int x)

{

IntParts.iNum=x;

printf("Byte 0 =%d", IntParts.Bytes.Byte0);

printf("Byte 1 =%d", IntParts.Bytes.Byte1);

printf("Byte 2 =%d", IntParts.Bytes.Byte2);

printf("Byte 3 =%d", IntParts.Bytes.Byte3);

}

Замечу, что идентификатор Bytes в описании структуры можно было опустить. В этом случае элементы Byte0…Byte3 находились бы не на третьем, а на втором уровне вложения и доступ к ним осуществлялся бы с помощью записи IntParts.Byte0, т.е., например:

printf("Byte 0 =%d", IntParts.Byte0);

Другое применение вложенных описаний структур и объединений – для описания сложных данных с полями различных типов.

Например, пусть программа описывает набор населённых пунктов. У каждого из них есть набор одинаковых параметров: название (Name), численность населения (Population) и тип населённого пункта (Type), который может быть равен 0 (город), 1 (посёлок), 2 (деревня).

А вот далее для каждого населённого пункта должен быть описан свой набор параметров (разумеется, они условны и приведены только для примера):

  • пусть для города - Площадь (Area) и названия районов (Districts)

  • для посёлка - название области (Region) и название центральной улицы (MainStreet)

  • для деревни – количество колхозников (Villagers) и количество фермеров (Farmers)

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

struct stInfo

{

char Name[255]; // Общие поля

int Population;

int Type;

union // Поля, специфичные для каждого типа

{

struct

{

int Area;

char Districts[10][255];

}City;

struct

{

char Region[255];

char MainStreet [255];

}Town;

struct

{

int Villagers;

int Farmers;

}Village;

};

}Info;

В ходе исполнения, в зависимости от значения поля Type, программа может работать с данными из элементов вложенных структур City, Town, Village. Например, если Type=0, то с помощью конструкции Info.City.Area можно узнать площадь города, а если Type=1, то нужно работать с полями Info.Town.Region и Info.Town.MainStreet. Разумеется, никто не возбраняет доступ и к другим полям вложенных структур, но это будет неправильно по смыслу программы.

В ходе разработки программы, структурированную запись данных можно бесконечно усложнять. Например, массив названий районов Districts можно заменить массивом структур Disctricts, тогда структура City будет выглядеть следующим образом:

struct

{

int Area;

struct stDistricts

{

char Name[255];

int Population;

char Area;

}Districts[10];

}City;