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

142 Глава 7

(Мы используем знак плюс для обозначения конкатенации строк. Эта операция обозначается одинаково в версиях языка Паскаль, которые поддерживают строки.) К процедуре failure обращаются тогда, когда в языке CLU явно или неявно будет сигнализировано состояние сбоя failure. Аргумент при обращении должен, конечно, идентифицировать проблему и операцию, в ко­торой она произошла. Обычно тип error.msg будет объявляться как некоторый тип строк. Если в используемом языке Паскаль строки не поддерживаются, аргумент может быть представлен как упакованный массив символов.

search ==ргос^а: int_array, х: int) returns (i: int)

signals (not- in)

effects Если переменная х находится в массиве а, то возвращается такой индекс i, что а [i] == х, в противном случае сигнализируется состояние not- in.

Эта спецификация иллюстрирует использование в языке CLU обработки исключительной ситуации, не связанной со сбоем. В языке Паскаль мы достигаем аналогичного эффекта при помощи следующей конструкции:

function searchi (var a: int. array; х: integer; var i: integer):

search I - exceptions modifies i

effects Если переменная х находится в массиве а, то индекс i устанавли­вается таким, что а [i] =; х, и возвращается значение ok; в противном случае возвращается значение not-in.

где searchl-exceptions является вычисляемым типом type searchLexceptions == (ok, not-in)

Отметим, что функция searchi имеет третий аргумент — параметр i с типом var. Эта переменная используется для получения ре­зультата в нормальном случае.

По соглашению все обращения к этой функции мы вставляем в предложение case следующим образом:

case searchi (а, х, i) of ok:a[i):=a[i]+l; not-in: write («Элемент не найден») end

Предложение case должно иметь ветвь, соответствующую каждому значению, которое может быть возвращено функцией. (Если возможны только две альтернативы, как в случае с функцией searchi, результат мор бы иметь булевский тип, а не вычисляе­мый тип, и оператор if мог бы использоваться вместо предложе­ния case.)

Этот подход имеет несколько недостатков. Неудобно, что функция searchi модифицирует параметр с типом var вместо выдачи

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

индекса, поскольку мы не сможем тогда ее использовать в таких выражениях, как a [search I (a, x)L Более того, функция searchi не так надежна при использовании, как процедура search. На­пример, предположим, что мы решили добавить еще одно значе­ние в тип searchi-exceptions. В соответствии с нашими соглаше­ниями надо добавить еще одну ветвь к каждому предложению case, в котором имеется обращение к функции searchi. Если, од­нако, это не будет сделано, то не возникнет ни ошибки во время компиляции, ни ошибок во время счета. (В языке Паскаль, если переключатель в предложении case не соответствует никакой из ветвей, программа продолжает выполнение g предложения, сле­дующего за предложением case.)

7.2. Абстракция данных

В этом разделе мы опишем некоторый подход для специфика­ции, использования и реализации абстракций данных при про­граммировании на языке Паскаль. Этот подход основывается сугубо на соглашениях по программированию. В языке CLU, наоборот, — компилятор обеспечивает непосредственную поддерж­ку этих абстракций. Данные соглашения разработаны в основном для того, чтобы показать, что мы можем реализовать абстракции данных, не разрабатывая повторно какие-либо модули, которые их используют, и что можем возвращать из функций абстрактные значения.

На рис. 7.1 показана спецификация абстракции данных для очереди целых чисел. В этой абстракции задается тип intqueue и набор операций, которые по соглашению допускаются для ра­боты с представлением этого типа. Имена всех операций начи­наются с префикса q. Будем следовать этому соглашению, чтобы избежать конфликтов с именами операций, используемых для дру­гих типов данных.

Отметим, что, несмотря на тот факт, что обе операции q-ap-pend и q-remfirst формально модифицируют очередь q, сама очередь q не передается, как некоторый тип var. Мы реализуем тип данных intqueue и другие абстрактные типы, используя ука­затели на неупорядоченный массив. Когда мы передаем в проце­дуру некоторый абстрактный объект, то, следовательно всегда передаем некоторую ссылку. Чтобы модифицировать абстрактный объект, модифицируем тот объект, на который указывает ссылка, а не саму ссылку. Таким образом, абстрактные объекты никогда не передаются, как параметры типа var.

Наше решение хранить абстрактные объекты в неупорядочен­ном массиве продиктовано тем, что надо реализовать типы, чьи объекты изменяют свой размер по мере работы программы. Мы настаиваем на том, чтобы представление было некоторой ссыл».

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