Чтение онлайн

на главную - закладки

Жанры

Шрифт:

К счастью, в Паскале эта задача решена: указатель на любой тип данных можно объявлять раньше того типа, на который он ссылается. Это единственное исключение из правила. Значит, представленное выше объявление типов вполне законно.

Вяжем список

Возьмемся за постройку списка для полицейской БД. Начнем с простого: вставим в список несколько элементов данных с номерами автомобилей и фамилиями владельцев, а затем распечатаем список. Это делает программа «P_54_1», рассмотрим её.

{ P_54_1 –

Размещение данных в несортированном списке }

type PRec = ^TRec; { Тип указатель на запись }

TRec = record { Тип записи для базы данных }

mNumber : integer; { Номер авто }

mFam : string[31]; { Фамилия владельца }

mNext : PRec; { Указатель на следующую запись }

end;

var List : PRec; { Указатель на начало списка (голова) }

{ Добавление в список записи об автомобиле }

procedure AddToList(aNumber: integer; const aFam : string);

var P : PRec;

begin

New(P); { Создаем динамическую переменную-запись }

{ Размещаем данные в полях записи }

P^.mNumber:= aNumber; P^.mFam:= aFam;

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), цикл не выполнится ни разу.

Поделиться:
Популярные книги

На границе империй. Том 9. Часть 4

INDIGO
17. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 4

Безумный Макс. Поручик Империи

Ланцов Михаил Алексеевич
1. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
7.64
рейтинг книги
Безумный Макс. Поручик Империи

Росток

Ланцов Михаил Алексеевич
2. Хозяин дубравы
Фантастика:
попаданцы
альтернативная история
фэнтези
7.00
рейтинг книги
Росток

Возвышение Меркурия. Книга 7

Кронос Александр
7. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 7

Мастер 3

Чащин Валерий
3. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 3

Охотник за головами

Вайс Александр
1. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Охотник за головами

Наследник жаждет титул

Тарс Элиан
4. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник жаждет титул

Беглец

Бубела Олег Николаевич
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Беглец

Курсант: назад в СССР 2

Дамиров Рафаэль
2. Курсант
Фантастика:
попаданцы
альтернативная история
6.33
рейтинг книги
Курсант: назад в СССР 2

Дорогами алхимии

Видум Инди
2. Под знаком Песца
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Дорогами алхимии

Сирийский рубеж

Дорин Михаил
5. Рубеж
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сирийский рубеж

Князь Серединного мира

Земляной Андрей Борисович
4. Страж
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Князь Серединного мира

Пустоцвет

Зика Натаэль
Любовные романы:
современные любовные романы
7.73
рейтинг книги
Пустоцвет

Младший сын князя. Том 2

Ткачев Андрей Юрьевич
2. Аналитик
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Младший сын князя. Том 2