3. Заполнить поля ELEM значениями UKSTR^.ELEM:='P';
UKZV^.ELEM:='A':
UKSTR | * | ® | P | UKZV | * | ® | A | |||
4. Заполнить поля SLED значениями UKSTR^.SLED:=UKZV;
UKZV^.SLED:=NIL:
UKSTR | * | ® | P | * | ® | A | Nil |
Это пример построения цепочки из двух звеньев. Если же звеньев много, то все следует делать в цикле. Рассмотрим пример образования и распечатки цепочки, состоящей из последовательности букв и заканчивающейся ".".
Несколько предварительных соображений по данному примеру:
1) для ссылки на цепочку как единое целое введен указатель UKSTR;
2) для ссылки на очередное звено в цепочке введен указатель UKZV;
3) для продвижения по цепочке от одного звена к другому нужно текущему указателю UKZV присваивать в качестве значения ссылку на это следующее звено: UKZV:= UKZV^.SLED;
4) т.к. поле SLED имеет тип SVYAZ, т.е. ссылку на запись, то можно записать UKZV^.SLED^.SLED, что означает переход на звено, находящееся через звено от исходного;
5) при организации цепочки будем использовать "нулевое" (заглавное) звено, которое указывает на первое звено цепочки и не содержит никакого элемента. Так поступают для удобства обработки цепочки в цикле.
ПРИМЕР 8. Формирование и распечатка цепочки символов
program SOZDANIE_ZEPOCHKI;
type SVYAZ = ^ZVSTR;
ZVSTR = record
elem: char; sled: SVYAZ;
end;
var UKSTR, UKZV: SVYAZ; SYM: char;
begin { Создание головного (нулевого) звена }
¦ new(UKSTR); UKZV:= UKSTR; UKZV^.sled:= nil;
¦ read(SYM);
¦ { Создание всей цепочки}
¦ while SYM <> '.' do
¦ begin
¦ ¦ new(UKZV^.sled); UKZV:= UKZV^.sled;
¦ ¦ UKZV^.elem:= SYM; UKZV^.sled:= nil;
¦ ¦ read(SYM);
¦ end;
¦ UKZV:= UKSTR^.sled; writeln; {Печать цепочки}
¦ while UKZV <> nil do
¦ begin
¦ ¦ write(UKZV^.elem,' ');
¦ ¦ UKZV:= UKZV^.sled;
¦ end;
end.
ПРИМЕР 9. Процедура удаления из списка SP элемента, содержащего в качестве данных некоторую букву
procedure UDALENIE_VNUTRI(var SP: SVYAZ; BUKVA: char);
var ZV: SVYAZ;
begin
¦ if SP = nil then writeln('Нет такого элемента!') else
¦ if SP^.elem <> BUKVA then UDALENIE(SP^.sled, BUKVA)
¦ else begin ZV:=SP; SP:=SP^.sled;
¦ dispose(ZV); end;
end.
ПОЯСНЕНИЕ. Данная процедура является рекурсивной. Выход из рекурсии осуществляется либо по нахождению и удалению соответствующей буквы, либо по достижению конца цепочки (обнаружение ссылки NIL). При удалении звена освобождается место в памяти с помощью DISPOSE.
Последний пример показывает, что для удаления одного элемента из цепочки достаточно применение одного оператора:
SP:= SP^.SLED.
И это действительно так, ибо устранение звена не есть его "физическое" уничтожение, а переброска ссылки на следующее звено, как это показано на схеме
SP | * | elem1 | * | elem2 | * | … | elemN | Nil | ||||
|
ПРИМЕР 10. Процедура удаления первого элемента цепочки
procedure UDALENIE_NACHALO(var SP: SVYAZ);
var Q: SVYAZ;
begin
¦ if SP^.sled <> nil then
¦ begin
¦ ¦ Q:= SP;
¦ ¦ SP:= SP^.sled;
¦ ¦ dispose(Q);
¦ end
¦ else writeln('Список пуст!');
end.
ПОЯСНЕНИЕ. Здесь введена вспомогательная переменная Q для временного хранения ссылки на удаляемое звено, прежде чем уничтожить его с помощью DISPOSE.
Вставка нового звена в цепочку занимает уже больше операций, т.к. для этого надо сделать две переброски: одну - из предыдущего звена на новое, вторую - из нового на следующее звено. Кроме того, необходимо образовать само это звено. Названные операции видны в следующей процедуре.
ПРИМЕР 11. Процедура вставки в список элемента, содержащего в качестве данных D, после элемента, содержащего X
procedure VSTAVKA_VNUTRI(var SP: SVYAZ; X, D: char);
var Q: SVYAZ;
begin
¦ if SP = nil then writeln('Нет такого элемента!')
¦ else if SP^.elem <> X then VSTAVKA(SP^.sled,X,D)
¦ else begin
¦ ¦ new(Q); Q^.elem:= D;
¦ ¦ Q^.sled:= SP^.sled; SP^.sled:= Q
end. end;
ПОЯСНЕНИЕ. Как и в примере 9, данная процедура является рекурсивной и по ней производится сначала поиск по цепочке звена, содержащего элемент Х, а затем сама вставка (если такое звено найдено).
ПРИМЕР 12. Процедура вставки звена в начало цепочки
procedure VSTAVKA_NACHALO(var SP: SVYAZ; D: char);
var Q: SVYAZ;
begin
new(Q); Q^.elem:= D;
Q^.sled:= SP^.sled;
SP^.sled:= Q
... .....-46.780 Program Prim24; Var r1,r2:real; BEGIN r1:=-46.78; r2:=-46.78; writeln('r1=',r1:12:3,' r2=',r2:9:4); writeln('_______________________________'); readln; END. 6. Массивы 6. 1. Описание массивов В языке Паскаль можно обрабатывать не только отдельные переменные, но и их совокупности. Одной из таких совокупностей (структурированных) данных является массив. ...
... . Объясните, для чего служат разрешения и привилегии в Windows NT. Зав. кафедрой -------------------------------------------------- Экзаменационный билет по предмету СИСТЕМНОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ Билет № 22 Перечислите возможности и инструменты системы программирования Microsoft Developer Studio. Укажите для чего предназначается буфер в системах ввода-вывода, ...
... с внешнего устройства (из входного файла) в основную память ЭВМ, операция вывода - это пересылка данных из основной памяти на внешнее устройство (в выходной файл). Файлы на внешних устройствах часто называют физическими файлами. Их имена определяются операционной системой. В программах на языке Паскаль имена файлов задаются с помощью строк. Например, имя файла на диске может иметь вид: ...
0 комментариев