Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
45
Добавлен:
23.03.2015
Размер:
884 Кб
Скачать

146 Глава 7

{Объявление типа представления для типа данных intqueue) type

intqueue = ^intqueiie_rep; intqueue_rep == ^г^иеие.^ет; intqueue_e!em == record val: integtr; next: intqtieue_rep; end;

{Начало реализации операций для типа данных intqueue} tunction q_new: intqueue; var q; intqueue; begin new (q); qf :== nil; q_new := q end {функция q_new};

function qJsempty (q: intqueue): boolean; begin qJsempty := (q^ = nil) end {функция qJsempty};

procedure q_append (q: intqueue; e: integer); var last_elem, elem: intqueue_rep; begin new (elem); ^ет^.уа) := e; elernf.next .'== nil; if qJsempty (q) then q^ := elem else begin last_elem :== qf; while last.elernf.next () nil do

last_elem :== last.elemf.next; last.elem^.next :== elem end;

end {процедура q_append}; tunction q_remfirst (q: intqueue): Integer; var oldq: infqueue_rep; begin

if qJsempty (q) (He удовлетворяются требования предложения requires} then failure (' К фрикции q_remfirst обратились с пустой очередью") else begin q.rernfirst :== q^.val; oldq :== qf;

qt ••= qTt-"ext:

dispose (oldq) {Освободить пространство, занимаемое удаленным элементом} end

end {функция q_rennfirst); procedure q_destroy (q: intqlieue) •var next.elem, old_elem: intqueue_rep; begin next.elem :•=. <\\', while next_elem ( ) nil do begin old_elem := next_elem; next_elem :=г next_elem•l•. next; dispose (old^elem); end; dispose (q) end {процедура q_destroy}; {Конец реализации операций типа данных intqueue}

Рис. 7,2. Реализация операций типа данных intqueue.

Использование языка Паскаль

Рис. 7.3. Очереди ql и q2 совместно используют одну и ту же очередь.

к памяти через повисающую ссылку, то может быть прочитана бессмысленная информация. Еще хуже модификации, сделанные через повисающие ссылки. Они могут нарушить непротиворечи­вость других объектов. Хотя при реализации па языке Паскаль можно обнаружить повисающие ссылки, такое обнаружение тру­доемко и поэтому обычно не делается. На рис. 7.2 приведена реализация типа данных intqueue, включая и операцию destroy.

По нашему соглашению следует, что каждый абстрактный тип, который представляется некоторым указателем, гарантирует, что присваивание абстрактных значений имеет тот же самый смысл, что и присваивание на языке CLU. Это не эквивалентно тому при­сваиванию, которое существует в языке Паскаль для встроенных в него типов. На языке Паскаль, например, присваивание мас­сива а 1: == а2 приводит к копированию массива а2. Последую­щие изменения в массиве а2 не влияют на массив а1. Если, с дру­гой стороны, мы напишем ql: = q2, где ql и q2 являются очере­дями целых чисел типа intqueue, то будет копироваться только указатель, а очереди ql и q2 будут совместно использовать оче­редь intqueue.

Важно, чтобы это совместное использование правильно рабо­тало. Последующие изменения в очереди q2 должны отражаться в очереди q), и наоборот. Мы достигаем этого, употребляя еще один уровень косвенного указания в представлении. Вместо того чтобы указывать непосредственно на первый элемент очереди, заголовки очередей ql и q2 указывают на некоторый указатель, который уже указывает на первый элемент очереди (рис. 7.3). Это позволяет нам удалять первый элемент из очереди и отражать это для обеих очередей ql и q2. Такое косвенное указание могло бы быть также сделано посредством некоторой записи, а не просто указателя. Например, предположим, что мы решили хранить размер очереди в представлении (это было бы полезным, если бы очереди целых чисел intqueue имели операцию size). Тогда бы мы задали следующее: intqueue_rep = record size: integer; first; lintqueue_ elem; end

Соседние файлы в папке POSIBNIK