Один из наиболее распространенных путей использования ссылочных типов - это последовательный "обход" элементов списка с выполнением определенных действий над данными, находящимися внутри каждого элемента. Подпрограмму, которая пошагово обрабатывает каждый элемент иногда еще называют итератором. Ниже приведен пример, который последовательно печатает значение каждого элемента в списке List_Nodes:
-- Предполагается, что "Start" ссылается на первый элемент списка. Current := Start; -- Устанавливаем текущий элемент на начало списка. while Current /= null loop -- пока есть данные: Put(Current.Data); -- Печатаем значение текущего элемента. Current := Current.Next; -- Переходим к следующему элементу списка. end loop;
Можно создавать и более сложные, чем рассмотренный нами список, структуры данных, если поместить внутри элемента несколько ссылочных переменных. Например, бинарное дерево является множеством элементов, для каждого из которых можно определить "родительский", "левый дочерний" и "правый дочерний" элементы. Кроме того, каждый элемент содержит некие данные (например Unbounded_String). С помощью ссылочных переменных довольно просто создать запись для элемента бинарного дерева:
type Tree_Node; -- Неполное описание типа. type Tree_Access is access Tree_Node; type Tree_Node is record Parent : Tree_Access; Left, Right : Tree_Access; Data : Unbounded_String; end record;
А вот пример использования этой древовидной структуры данных; при этом A и B имеют тип Tree_Access:
A := new Tree_Node; B := new Tree_Node; A.Data := To_Unbounded_String("Hello!"); -- присваиваем значение B.Data := To_Unbounded_String("Goodbye!"); A.Left := B; -- связываем элементы. B.Parent := A;
Если компонент для хранения данных представляют собой ссылочную переменную, то его можно использовать точно также, как и любую другую ссылочную переменную. Поэтому встречаются инструкции, содержащие несколько точек (.) Например, после запуска приведенной выше программы значением переменной A.Left.Data будет "Goodbye!".
При использовании ссылочных типов легко ошибиться и связать элементы неправильно. Поэтому, лучше всего сразу создавать подпрограммы, которые будут все делать корректно, и затем использовать их. Например, можно написать подпрограмму, которая автоматически создает новый элемент, задает его значение и <<присоединяет>> к уже существующиму элементу в нужном месте. Наилучший подход состоит в использовании существующих компонентов, соответствующих Вашим требованиям, если такие имеются.
В приведенном выше примере с древовидной структурой, какое значение будет иметь B.Parent.Data?
Перейти к предыдущему разделу | Перейти к следующему разделу | Вернуться к содержанию Урока 12 |
---|
David A. Wheeler (dwheeler@ida.org)
Исходная копия этого документа находится по адресу
"http://www.adahome.com/Tutorials/Lovelace/s12s4.htm".
Исходная копия перевода размещена на сайте http://www.ada-ru.org
Перевод: Юрий Королев
Общая редакция перевода: Г.Ю. Сисюк