Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
информатика.doc
Скачиваний:
74
Добавлен:
09.02.2015
Размер:
450.05 Кб
Скачать

3 Структуры

Описание структур

Структуры — это наборы (иногда их называют агрегатами) логически связанных переменных, объединенных под одним именем Структуры часто испо­льзуются, чтобы определить записи, которые должны сохраняться в файлах. Указатели и структуры могут служить ба­зой для создания более сложных структур данных, таких как связанные спис­ки, очереди, стеки и деревья.

Структуры — это производные типы данных, они создаются из объектов других типов. Рассмотрим следующее описание структуры;

struct card

{

char *face;

char *suit;

};

Ключевое слово struct определяет структуру. Идентификатор card являет­ся именем-этикеткой структуры. Имя-этикетка именует структуру, и испо­льзуется совместно с ключевым словом struct для объявления переменных типа структуры. В данном примере тип структуры - struct card. Перемен­ные, объявленные внутри скобок структуры, являются элементами структу­ры Определение struct card содержит два элемента типа char * - face и suit.

Объявление

struct card a, deck[52], *cPtr;

объявляет а - переменную типа struct card, deck - массив из 52 элементов типа struct card и cPtr - указатель на struct card. Можно объявить перемен­ные данной структуры и по-другому, разместив разделенный запятыми список переменных между закрывающей скобкой определения структуры и точкой с запятой, завершающей ее определение. Например, указанное выше объявле­ние, объединенное с определением структуры, будет выглядеть следующим об­разом:

struct card

{

char *face;

char *suit;

} a, deck[52], *cPtr;

Имя-этикетка не является для структуры обязательным. Если определе­ние структуры не содержит имя-этикетку, переменные для этой структуры могут быть объявлены только в определении структуры, но не отдельным объ­явлением.

Инициализация структур

Структуры можно инициализировать, как и массивы, используя список инициализации. Чтобы инициализировать структуру, после имени перемен­ной в объявлении структуры ставится знак равенства, за которым следует по­мещенный в фигурные скобки, разделенный запятыми список инициализато­ров. Например, объявление

struct card a = {"Three", "Hearts"};

создает переменную а типа struct card (структура определена выше) и присваи­вает элементу face значение "Three", а элементу suit значение "Hearts", Если инициализаторов в списке меньше, чем элементов в структуре, остальным эле­ментам автоматически присваивается значение 0 (или NULL, если элемент — указатель). Переменным-структурам, объявленным вне определения любой функции (т.е. глобально) присваиваются 0 или NULL, если они явно не иници­ализированы во внешнем объявлении. Структуры можно инициализировать и с помощью оператора присваивания. При этом можно либо присвоить перемен­ной-структуре переменную того же типа, либо присвоить значения отдельным элементам структуры,

Доступ к элементам структур

Для обращения к элементам структур используются две операции: опера­ция элемента структуры (.), также называемая операцией-точкой, и опера­ция указателя структуры (->), также называемая операцией-стрелкой. Опе­рация элемента структуры обращается к элементу через имя переменной структуры. Например, для того чтобы напечатать элемент suit структуры а из предыдущего объявления, можно написать оператор

printf("%s", a.suit);

Операция указателя структуры, состоящая из знака минус (-) и знака бо­льше (>) без пробела между ними, обращается к элементу через указатель структуры. Предположим, что переменная aPtr была объявлена как указатель на struct card и ей был присвоен адрес структуры а. Чтобы напечатать эле­мент suit структуры а при помощи указателя aPtr, напишите оператор

printf ("%s", aPtr->suit);

Typedef

Ключевое слово typedef предоставляет программисту механизм для созда­ния синонимов (или псевдонимов) для ранее определенных типов данных. Ча­сто используют typedef для того, чтобы дать укороченное имя структурному типу. Например, оператор

typedef struct card Card;

определяет новый тип с именем Card, как синоним типа struct card. Пишу­щие на С часто используют typedef, чтобы определить тип структуры, при этом отпадает необходимость в имени-этикетке, Например, следующее опре­деление

typedef struct

{

char *fасе;

char *suit;

} Card;

создает тип Card без использования отдельного оператора typedef.

Теперь Card можно использовать для объявления переменных типа struct card. Объявление

Card deck [52];

описывает массив, состоящий из 52 структур Card (т.е. переменных типа struct card).

Объединения

Объединение - производный тип данных, подобный структуре, элементы которого разделяют одну и ту же область памяти. На различных этапах вы­полнения программы одни переменные могут оказаться невостребованными, в то время как другие, наоборот, используются только в этой части программы, поэтому объединения экономят пространство вместо того, чтобы впустую тра­тить память на не использующиеся в данный момент переменные. Элементы объединения могут принадлежать к любому типу. Число байтов, используемое для хранения объединения, должно быть, по крайней мере, достаточным для хранения наибольшего из элементов. В большинстве случаев объединения со­держат два или более типа данных. Ссылаться в данный момент времени мож­но только на один элемент и, соответственно, только один тип данных. Задача программиста - обеспечить, чтобы на данные, хранящиеся в объединении, ссылались как на данные соответствующего типа.

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

union number

{

int x;

float y;

};

означает, что number является типом union с элементами int x и float у..

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

union number value = {10};

однако объявление следующего вида будет ошибочным:

union number value = {1.43};

Структуры, ссылающиеся на себя

Мы уже изучали ранее структуры данных фиксированного размера, та­кие, как одномерные массивы, двумерные массивы и структуры. В этой главе будут рассмотрены динамические структуры данных, размер которых, может увеличиваться или уменьшаться при исполнении программы

Структуры, ссылающиеся на себя, содержат в качестве элемента указа­тель, который ссылается на структуру того же типа. Например, определение

struct node

{

int data;

struct node *nextPtr;

};

описывает тип struct node. Структура типа struct node состоит из двух элемен­тов - целого data и указателя nextPtr. Элемент nextPtr указывает на структу­ру типа struct node - структуру того же самого типа, что и только что объявленная нами, отсюда и термин «структура, ссылающаяся на себя». Эле­мент nextPtr иногда называют связкой, т.е. nextPtr можно использовать для того, чтобы связать структуру типа struct node с другой структурой того же типа Рис. 4 иллюстрирует две структуры, ссылающиеся на себя, связанные друг с другом и образующие список. Заметьте, что в связывающем элементе второй структуры нарисована представляющая указатель NULL косая черта, чтобы показать, что этот элемент не указывает на другую структуру. Указатель NULL обычно обозначает конец структуры данных, так же как символ NULL обозначает конец строки.

Рис. 4 Две ссылающиеся на себя структуры, связанные друг с другом