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

Замечания по поводу операций up и down

Полезно представлять себе операциюupкак окружение объ’екта типа представления непроницаемой заслонкой. Тому, кто использует операциюup, сквозь эту заслонку не видно представ­ления. Значение объекта можно исследовать только вызовом при­митивных операций, соответствующих типу объекта. Например, пользователь не видит массива, который представляет наборintset, но может сказать, какие элементы имеются в наборе, и может добавлять или удалять элементы, обращаясь к соответ­ствующим операциям.

Операция downпроизводит обратное действие по отношению кup —она убирает заслонку. Если бы для пользователя имелась возможность обращаться к down,то ему было бы доступно кон­кретное представление абстрактного объекта и выгоды абстрак­ции данных были бы утеряны. Поэтому языкCLUпозволяет использовать операцию downтолько в кластере, который реали­зует объект.

Чтобы избежать возникновения фальшивых объектов, огра­ничивается также и использование операции up.Если бы эту операцию можно было использовать вне определяющего кластера, было бы возможно создавать объекты, которые выглядели как объекты типа, но которые при передаче их операциям кластера в качестве аргумента имели бы другое, чем ожидается, пред­ставление, что приводило бы к всевозможным очень неприятным ошибкам. Поэтому, чтобы использование абстракций данных было выгодно, ограничение сферы применения операций upи down необходимо.

Как уже говорилось, если операцияdownиспользуется внутри кластера, то она убирает заслонку и представление объекта ста­новится видимым. Однако это представление есть просто другой абстрактный объект, и он защищен заслонкой, сконструирован­ной его собственной реализацией, которая может быть либо оп­ределенным пользователем кластером, либо частью реализации языкаCLU. Реальное представление объекта снова недоступно, но информация об объекте может быть получена при помощи операций. Так, внутри кластераintsetнам недоступна внутрен­няя структура массива, который реализуетintset, но мы можем исследовать и изменять интересующую нас информацию, исполь­зуя операции работы с массивом.

Для операцийupиdown(и следовательно, дляcvt) не гене­рируется никакого объектного кода. Они лишь информируют компилятор о том, что способ рассмотрения объекта изменился. Компилятор использует эту информацию для контроля типов. Так как контроль типов производится во время компиляции, эта информация не нужна при выполнении, хотя она и может быть по­лезна для отладки.

Использование абстракций данных

Если абстракция данных определена, то она не отличается от встроенных типов и ее объекты и операции должны использо­ваться точно так же, как объекты и операции встроенных типов. Насколько это возможно, зависит от используемого языка про­граммирования. В языке CLUмогут быть объявлены переменные нового типа. Как, например,i:intset. Создавать объекты и мани­пулировать ими можно следующим образом;

ii = intset$create ( ) intset$insert (i, 3)

На рис. 4.6представлена спецификация и реализация про­цедурыremove_dupls. Эта реализация использует тип данныхintsetдля запоминания уже имеющихся в массиве элементов. Определенные пользователем типы могут также использо­ваться для представления других определяемых пользователем типов. Например, если мы собираемся реализовать для банков­ской системы тип данныхaccount(счет), то может оказаться по лезным отслеживать индивидуальные вклады (deposits), снятия (withdrawls) и совокупный баланс (balance).

femove_dupls=proc(a: array int])

modifiesa

effectsУдаляет из а все дубли элементов. Нижняя граница а остается той же самой, но расположение оставшихся элементов может изме­ниться. Например, если до обращения а = [1: 3, 13, 3, 6],то при возврате а имеет нижнюю границу 1 и содержит три элемента 3, 13 и 6, расположенных некоторым образом.

ai = array [int]

remove_dupls = proc (a: ai)

a_low: int :== ai$low (a)

i: int : = a_low j: int: = a_low

s: intset := intset$create () while i <= ai$high (a) do

if ~ intset$mernber (s, a [i])

then intset$insert (s, a [i]) % a [i] не дубль. Оставить его,

a [j] := a [i]

j:-j+i end i:=i+ 1

end

ai$trim (a, a_low, j - a_low) % удалить остальные элементы a

end remove_dupls

Рис, 4.6.Использование типа данныхintset.

Таким образом, мы можем иметь

гер = record [balance: int, deposits, withdrawls: intset ]

Здесь мы используем тип данных intsetдля представления счетов.

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