Смекни!
smekni.com

Лекции по Паскалю (стр. 5 из 6)

type T=<тип>;

var p:=^T;

…………….

new(p);

…………….

dispose(p);

_________________

getmem (p, sizeof(T));

……………..

freemem (p, sizeof(T));

В общем случае getmem и freemem дают большую свободу действий по сравнению с new и dispose, т.к. позволяют работать без привязки к конкретному типу переменных:

type zap=record

x,y:integer;

end;

st=string [20];

var p:pointer;

begin getmem (p,100); zap(p^).x:=124; zap(p^).y:=47; ………………

real(p^):=0.213; ……………….

st (p^):= ‘Привет’; ……………….

freemem(p,100);

Вопрос №38.Процедуры mark и release.Пр-ры dispose/freemem освобождают участок того же размера, кот. был выделен пр-рами new/getmem. Эти участки могут исп-ся для хранения дин. переменных. Однако в ряде версий Pascal с-ма не выполняет автоматических действй по поиску и объединению разрозненных фрагментов памяти в одну непрерывную область. Пр-ры mark и release были разработаны для более эффективного размещения дин. переменных и устранения фрагментации памяти.mark(p1);p1 – перем. типа указательmark присваивает параметру р1 адрес начала свободной области дин. памяти. Помеченная область с пом. new/getmem исп-ся для размещения дин. переменных. Когда данные дин. переменные окажутся ненужными, занимаемую ими память можно освободить: release(p1).release освобождает память, начиная с адреса, полученного в рез-те выполнения последней пр-ры mark, значение р1=nil.

Параметр пр-ры mark нельзя исп-ть в кач-ве параметра пр-ры new/getmem и его нельзя изменять до использования в проге release.

Возможна вложенность пр-р mark, тогда каждой mark соответствует своя release.

Пример:

var p1,p2:^integer;

………………

mark(p1); ……………… new(p); new(q); ……………… mark(p2);

new(x); ……………… release(p2);……………… release(p1);

!!! В одной и той же проге не рекомендуется исп-ть одновременно dispose/freemem и mark/release.

Вопрос №39.

Динамические цепочки. Объявление. Алгоритм формирования цепочки.

Д. цеп. – аналог строк текущей длины.

Эл-ты строки можно размещать в памяти произвольно, если каждый эл-т снабдить явным указанием места, где находится след. эл-т. В этом случае каждый эл-т строки должен состоять из двух полей: в одном – символ строки, в другом – адрес след. эл-та. Каждая такая пара полей наз. звеном. Ссылки сцепляют звенья в единую цепочку. Такой способ представления упорядоченной послед-сти эл-тов наз. сцеплением. Оно применяется для представления дин. структур любой сложности. Тело звена – информац. часть, справочная часть звена – адрес звена (след., пред., и т.д.).

Для представления звена цепочки необход. исп-ть запись их 2-х полей.

type adr=^zveno;

zveno=record

element:char;

adrsled:adr;

end;

Последнее звено цепочки должно быть снабжено ссылкой nil. Для работы с цепочкой должна исп-ся ссылка на 1-е звено

varadr1:adr;

1-й элемент

adr1

Для удобства работы с цепочкой в нее включается заглавное (нулевое) звено. В поле adrsled заглав. звена содержится адрес первого звена цепочки.

☻Пример (формирование цепочки):

type -//-;

varadr1, adrzv:adr; {adr1 – адрес 1-го звена, adrzv – адрес текущего звена}

simv:char;

begin

new(adr1);

adrzv:=adr1;

adrzv^.adrsled:=nil; {при формировании цепочки текущее звено всегда явл. последним}

read(simv);

while simv<>’.’ do

begin

{1} new(adrzv^.adrsled);

{2} adrzv:=adrzv^.adrsled;

{3} adrzv^.element:=simv;

{4} adrzv^.adrsled:=nil;

{5} read(simv);

end;

Алгоритм формирования цепочки (в примере):

1. Отвести область памяти для очередного звена. Его адрес занести в адресную часть текущего звена.

2. Новое звено сделать текущим звеном.

3. В поле element текущ. звена занести прочитанный символ.

4. В адресную часть текущ. звена занести nil.

5. Прочитать очередной символ и перейти к п.1.

Вопрос №40.

Операции, определенные над динамическими цепочками.

Над цепочкой опред. 3 операции:

1. Поиск эл-тов в цепочке.

2. Вставка эл-тов в произвольное место в цепочке.

3. Удаление заданного эл-та.

¬ Для перехода от одного звена цепочки к след. необход. в цикле выполнять оператор: adrzv:=adrzv^.adrsled. Этот оператор аналогичен i:=i+1 для обычных статических цепочек.

…………………

adrzv:=adr1;

k:=0;

read(bukva);

while adrzv^.adrsled<>nil do

begin

adrzv:=adrzv^.adrsled;

if adrzv^.element=bukva then k:=k+1;

end;

® Удаляемый эл-т задается ссылкой на пред. звено, при этом учитывается, что если какое-либо звено сущ-ет, но на него нет ссылки из другого звена, то оно не доступно

Для исключения эл-та из строки необходимо изменить ссылку у предшествующего ему эл-та. В кач-ве новой ссылки у этого эл-та необход. принять ссылку из исключаемого эл-та.

adrzv^.adrsled:=adrzv^.adrsled^.adrsled.

procedure Del (zv:adr);

var a:adr;

begin

a:=zv^.adrsled;

zv^.adrsled:=zv^.adrsled^.adrsled;

dispose(a);

end;

­ Вставка основывается на объединении отдельных звеньев в единую цепочку.

Алгоритм вставки:

1. Создать новую дин. переменную типа zveno.

2. В поле element этой переменной занести вставляемый эл-т.

3. В поле adrsled этой переменной занести ссылку, взятую из поля adrsled пред. звена.

4. В поле adrsled пред. звена занести адрес вставляемого звена.

procedure Insert (zv:adr; el:char);

var q:adr;

begin

{1} new(q);

{2} q^.element:=el;

{3} q^.adrsled:=zv^.adrsled;

{4} zv^.adrsled:=q;

end;

Дин. цепочка явл. частным случаем линейного однонаправленного списка. В цепочке информационными эл-тами явл. символы (char). В общем случае информац. эл-тами могут быть значения любого типа. Принцип организации информац. эл-тов в список тот же.

typeadres1=^zveno1;

zveno1=record

adrsled:adres1;

element:<тип_эл-та_списка>;

end;

Вопрос №41.

Двунаправленные списки. Объявление. Способы организации колец. Формирование кольца (по первому способу).

Недостатки линейного однонаправленного списка: по нему можно двигаться только в одном направлении (от начала к концу).

2-направл. списки позволяют двигаться по списку в любом направлении. Каждое звено 2-нопраленного списка списка содержат 2 поля ссылочного типа: на последнее и на предыдущее звено.

Структура опред. следующим описанием.

Объявление.

Type

Adr2=^Zveno2;

Zveno2 = Record

Adrcled: Adr2;

Adrpred: Adr2;

Element: <Тип_элемента_списка>;

End;

Кольцевые списки.

(1 способ) На осн. 2-направленного списка могут быть организованы 2-направленные кольцевые списки.

В кольц. списке значение поля Adrcled последнего звена – ссылка на начальное звено, а Adrpred начального звена – ссылка на последнее звено.

(2 способ) заглавное звено не включают в кольцо.

Достоинство: проще реализуется вставка нового звена, как в начало списка, так и в конец.

Недостатки: 1 способа: при циклических обработках, элементы списка необходимо проверять: не является ли очередное звено заглавным звеном.

У 2 способа данный недостаток отсутствует, но труднее реализовать добавление звена в конец списка.

Над 2-направленными списками определены операции: поиск элемена в списке, вставка и удаление.

Вопрос №43.

Операции, определенные над двунаправленными кольцевыми списками. Примеры (для 1-го способа организации колец).

1)Встака эл-та

Алгоритм – порождение нового звена;

- занесение вставленного элемента в информационное поле порожденного звена.

1) записать в поле Аdrcled ссылки на след эл-т из звена предшествующему вставляемому;

2) занести в Аdrpred ссылки на предшеств.эл-т из звена следующ. вставляемому;

3) занести в Аdrpred след. за вставл. звено ссылки на вставляемое звено;

4) в Аdrpred предшествующего звена ссылки на вставляемое звено;

Procedure Vstsv

(Elem: <Тип_элемента>)

{1} New (Q);

{2} Q^.Element:=Elem;

{3} Q^.Adrcled:=PredZV^.Adrcled;

{4} Q^.Adrpred:=PredZV;

{5} PredZV^.Adrcled^. Adrpred:=Q;

{6} PredZV^.Adrcled:=Q;

End;

Создание 2-направленного кольцевого списка с заглавным звеном.

Для создания кольцевого списка, после создания любого звена, список нужно закольцевать.

Var

Ring: Adr2; (адрес заглавного звена)

Bykva: Char;

Begin

New(Ring);

Ring^.Adrcled:=Ring;

Ring^.Adrpred:=Ring;

While Bykva< >’.’do

begin

Vstav(Bykva, Ring^.Adrcled);

Read(Bykva);

End.

Удаление элемента.

1. занес. в Аdrpred след. за удаляемым звеном ссылку на предшествующий удаляемому звену;

2. в Аdrcled предшеств. удаляемому звену ссылки на след. за удаляемым звеном;

3. уничтожение удаляемого звена.

{1} Adrzv^.Adrcled^. Аdrpred:=Ydzv^. Аdrpred;

{2} Ydzv^. Аdrpred^. Аdrcled:= Ydzv^. Аdrcled;

{3} Dispose(Ydzv);

Поиск элемента.

Аналогичен поиску элементов в цепочке, но в кольцевом списке формально нет последнего элемента.

Q:=P^. Аdrcled; (Р-адрес заглавного звена)

While (P< >Q) and not B do (Q-адрестекущегозвена)

Вопрос №45.

Очередь FIFO. Объявление. Операции, определенные над очередью FIFO. Организация очереди FIFO.

Очередь (FIFO).

Для организации такой очереди исп-ся 2 ссыл. переменные типа

adr1:Left – указывает на начало очереди;

adr2:Right - указывает на конец очереди.

Добавление осуществляется в соответствии со значением right. Затем это значение изменяется и указывает на последний занесенный эл-т.

Выборка осуществляется в соответствии со значением Left. Затем изменяется и указывает на след. эл-т очереди. Если в очереди всего 1 эл-т, то Right=Left. Обычно это исп-ся как прзнак окончания очереди при выборе.