| 7.3.      Работа со структурами данныхВозможность выделения и освобождения области памяти позволяет создавать структуры данных с переменным числом элементов - динамические структуры. Чаще всего используют т. н. связанные структуры, когда среди элементов устанавливается некоторая иерархия, например наподобие генеалогического дерева. Среди таких структур наибольшее распространение в различных практических приложениях получили линейные структуры (списки) и структуры-деревья (более подробно о разнообразии структур см., например, [6,7]. В связных структурах обычно используются однотипные элементы. Каждый элемент имеет две различные части:
 информационную часть - та часть, которая содержит всю информацию о том или ином объекте (например если это структура целых чисел, то значение конкретного числа);ссылку на соседний элемент (соседние элементы) в конкретной иерархии элементов (например, если структура является списком, то ссылка на элемент, стоящий в списке непосредственно за данным элементом, а может быть, и на предыдущий элемент).
 Наиболее удобно для фиксации такой информации использовать тип-запись. Однако при задании такого типа элемента возникает определенная трудность, связанная с тем, что этот тип должен содержать тип-указатель на элемент структуры, который, в свою очередь, нельзя определить, пока не определен тип элемента. При этом, в какой бы последовательности ни определялись эти типы, будет нарушено правило, гласящее, что использовать можно только те элементы программы, которые определены ранее. Для устранения этого препятствия в языке Паскаль сделано исключение из указанного правила по отношению к двум типам данных, один из которых является типом-указатель на объект второго типа. Пример.  Тип элемента структуры, содержащего символьную информацию в виде строки. 
   | type |  |  
   | pPoint = ^Elem; | {указатель на элемент} |  
   | Elem = record |  |  
   | Info: string[80]; |  |  
   | Point: pPoint |  |  
   | end; | {тип элемента структуры} |  При работе с динамическими структурами данных выполняются следующие основные операции:
 добавление элемента структуры;исключение элемента структуры;поиск элементов структуры по какому-то признаку.
 В разных структурах эти операции выполняются по-своему. В качестве примера рассмотрим добавление и исключение элементов из линейного списка, называемого очередью, - структуры, в которой добавление элементов осуществляется с одной стороны, а исключение - с другой стороны списка. Пусть элемент структуры имеет информационную часть, представляющую собой одно целое число. Тогда тип такого элемента может выглядеть следующим образом: type pPoint= ^Elem; Elem = record
 Info:   Integer;
 Point:   pPoint
 end;
 Для работы с очередью введем следующие переменные:  varРо,   РоВ,   РоЕ:   pPoint;
 X:   Integer;
 Предположим, что вначале в очереди нет элементов - очередь пуста. Этот факт можно зафиксировать следующим образом (рис. 1 а): 
|  |  | Рис. 1. Последовательность работы с очередью |  Введем в очередь первый элемент. Для этого можно выполнить следующие действия: 
   | Read(X) ; | {чтение значения первого элемента} |  
   | New(Po); | {выделение области под элемент} |  
   | Po^.Info := X; | {информационная часть} |  
   | Ро^.Point := nil; | {нет следующего элемента} |  
   | РоВ := Ро; | {указатель начала очереди} |  
   | РоЕ := Ро; | {указатель конца очереди} |  После выполнения этих операторов возникнет ситуация, изображенная на рис. 1 б. На этом рисунке прямоугольником указан элемент очереди. Левая часть прямоугольника представляет собой информационную часть, а правая - ссылку на следующий элемент. Стрелками изображены указатели. Для добавления следующего элемента можно записать: 
   | Read(X) ; |  |  
   | New(Po); |  |  
   | Po^.Info := X; |  |  
   | Ро^.Point := nil; |  |  
   | РоE^.Point   := Ро; | {установление  связей} |  
   | РоЕ   := Ро; |  |  Полученная ситуация изображена на рис 1 в. Рассмотренные выше две последовательности операторов по добавлению элементов похожи друг на друга и могут выполняться в цикле (с небольшой модернизацией). Посмотрим теперь, как удалить первый элемент из очереди. Для этого можно выполнить следующие действия:  
   | if  Pon <> nil  then |  |  
   | begin |  |  
   | Ро   := РоВ^.Point; | {указатель на второй  элемент} |  
   | Dispose (PoB); | {освобождение  области} |  
   | РоВ   := Ро |  |  
   | end; |  |  Полученная ситуация изображена на рис. 1 г. При освобождении элементов структуры следует особое внимание уделять сохранению необходимых связей, т. к. в противном случае можно потерять часть или даже все оставшиеся элементы структуры. В рассмотренном примере для этой цели использовалась переменная Ро. 
 
 |