Читаем Песни о Паскале полностью

P^.mNext:= List; { Цепляем предыдущую запись к новой записи }

List:= P;       { Теперь голова указывает на новую запись }

end;

      { Распечатка списка }

procedure PrintList;

var P : PRec;

begin

P:= List;

while Assigned(P) do begin

      Writeln(P^.mNumber, '':3, P^.mFam);

      P:= P^.mNext;

end;

end;


begin { Главная программа }

List:= nil;

AddToList(10, 'Иванов');

AddToList(20, 'Петров');

AddToList(30, 'Сидоров');

PrintList;

Readln;

end.


Основу программы составляют процедуры вставки в список и его распечатки. В процедуре AddToList – добавить в список – первые строки вам знакомы: после создания динамической переменной P^ данные копируются в её поля. Обратите внимание на то, что указатель P – это локальная переменная, которая исчезнет после выхода из процедуры. И тогда, если не сохранить этот указатель, адрес новой переменной будет утерян, что приведет к утечке памяти. Поэтому после создания новой переменной P^ адрес из головы списка List копируется в поле mNext вновь созданной записи, и адрес новой записи P помещается в голову списка. Вот эти операторы.


P^.mNext:= List; { Цепляем предыдущую запись к новой записи }

List:= P;  { Теперь голова указывает на новую запись }


Все просто, но если эти строки поменять местами, катастрофа неминуема!

Следующие рисунки показывают порядок наращивания списка. Здесь локальная переменная P обведена пунктиром, что отмечает её временный характер. Пунктирные стрелки с цифрами отмечают порядок выполняемых действий.

На рис. 121 и рис. 122 выполняется вставка первого элемента. В начальный момент, когда список ещё пуст, его голова – глобальная переменная List – содержит заглушку NIL, помещенную туда главной программой.

В результате присваивания оператором


      P^.mNext:= List;


значение NIL попадает в поле новой переменной P^.mNext (после создания переменной это поле было не определено и содержало мусор).



Рис.121 – Состояние списка перед вставкой первого элемента

Следующий затем оператор


      List:= P;


сохраняет указатель на вновь созданную переменную в голове списка List. Теперь, перед выходом из процедуры, на эту переменную ссылаются уже два указателя (рис. 122). Но поскольку P – это локальная переменная, которая вскоре исчезнет, то после выхода из процедуры единственной ссылкой на первый элемент останется голова списка List.



Рис.122 – Состояние списка после вставки первого элемента

Следующая пара рисунков показывает вставку второго и последующих элементов. Сначала адрес бывшего первого элемента копируется из головы списка List в поле mNext вновь созданной переменной. Теперь доступ ко всем последующим элементам возможен через это поле. А следующий оператор ставит во главе списка вновь созданную переменную. Так новичок возглавляет список, оттесняя старожилов на последующие места.



Рис. 123 – Состояние списка перед вставкой второго элемента



Рис. 124 – Состояние списка после вставки второго элемента

Распечатка списка

Теперь рассмотрим процедуру распечатки списка PrintList. Кто скажет, что она проста? Не проста, а очень проста! Подобные ей процедуры обработки списков строятся на основе цикла While. Скелет такой типовой процедуры показан ниже.


      P:= List;

      while Assigned(P) do begin

      { Здесь обрабатывается элемент списка }

      P:= P^.mNext; { переход к следующему элементу }

      end;


На входе в цикл указатель P загружается из головы списка. Внутри цикла, после обработки очередного элемента, переходим по указателю mNext к следующему. Напомню, что функция Assigned(P)равнозначна выражению P<>NIL. Таким образом, цикл завершится после обработки последнего элемента списка, поскольку его поле mNext содержит NIL. А если список пуст (голова содержит NIL), цикл не выполнится ни разу.

Программа «P_54_1» покажет на экране следующий результат.


30 Сидоров

20 Петров

10 Иванов


Как и следовало ожидать, порядок элементов в списке оказался обратным порядку вставки в него. Этим можно воспользоваться для построения стека, что мы и сделаем в свое время.

Поиск в несортированном списке

Углубившись в списки, мы чуть не забыли о нашем пользователе – полицейском. А ведь ему придется искать в базе данных информацию об угнанных автомобилях. Дополнив предыдущую программу функцией поиска, получим представленную ниже программу «P_54_2». Для экономии бумаги я не показал здесь процедуры вставки и распечатки списка.


Перейти на страницу:

Похожие книги

Сломанная кукла (СИ)
Сломанная кукла (СИ)

- Не отдавай меня им. Пожалуйста! - умоляю шепотом. Взгляд у него... Волчий! На лице шрам, щетина. Он пугает меня. Но лучше пусть будет он, чем вернуться туда, откуда я с таким трудом убежала! Она - девочка в бегах, нуждающаяся в помощи. Он - бывший спецназовец с посттравматическим. Сможет ли она довериться? Поможет ли он или вернет в руки тех, от кого она бежала? Остросюжетка Героиня в беде, девочка тонкая, но упёртая и со стержнем. Поломанная, но новая конструкция вполне функциональна. Герой - брутальный, суровый, слегка отмороженный. Оба с нелегким прошлым. А еще у нас будет маньяк, гендерная интрига для героя, марш-бросок, мужской коллектив, волкособ с дурным характером, балет, секс и жестокие сцены. Коммы временно закрыты из-за спойлеров:)

Лилиана Лаврова , Янка Рам

Современные любовные романы / Самиздат, сетевая литература / Романы