Сравнение языков программирования (esyr) (1161143), страница 7
Текст из файла (страница 7)
Эти процедуры служат командами.MODULE Trees; (* экспорт: Tree, Node, Insert, Search, Write, Init *)IMPORT Texts, Oberon; (* экспорт только для чтения: Node.name *)TYPETree* = POINTER TO Node;Node* = RECORDname-: POINTER TO ARRAY OF CHAR;left, right: TreeEND;VAR w: Texts.Writer;PROCEDURE (t: Tree) Insert*VAR p, father: Tree;BEGIN p := t;REPEAT father := p;IF name = p.name^IF name < p.name^UNTIL p = NIL;NEW(p); p.left := NIL;IF name < father.name^END Insert;(name: ARRAY OF CHAR);THEN RETURN END;THEN p := p.left ELSE p := p.right ENDp.right := NIL; NEW(p.name, LEN(name)+1); COPY(name, p.name^);THEN father.left := p ELSE father.right := p ENDPROCEDURE (t: Tree) Search* (name: ARRAY OF CHAR): Tree;VAR p: Tree;BEGIN p := t;WHILE (p # NIL) & (name # p.name^) DOIF name < p.name^ THEN p := p.left ELSE p := p.right ENDEND;RETURN pEND Search;PROCEDURE (t: Tree) Write*;BEGINIF t.left # NIL THEN t.left.Write END;Texts.WriteString(w, t.name^); Texts.WriteLn(w); Texts.Append(Oberon.Log, w.buf);IF t.right # NIL THEN t.right.Write ENDEND Write;PROCEDURE Init* (t: Tree);BEGIN NEW(t.name, 1); t.name[0] := 0X; t.left := NIL; t.right := NILEND Init;BEGIN Texts.OpenWriter(w)END Trees.Загруженный модуль может вызывать команду незагруженного модуля, задавая ее имя как строку.
Специфицированный модуль при этом динамическизагружается и выполняется заданная команда. Динамическая загрузка позволяет пользователю запустить программу как небольшой набор базисных модулей ирасширять ее, добавляя последующ ие модули во время выполнения по мере необходимости. Интерфейс модуля (объявления экспортируемых объектов)извлекается из модуля так называемым смотрителем, который является отдельным инструментом среды Оберон.Modula-2open in browser PRO version[править]Are you a developer? Try out the HTML to PDF APIpdfcrowd.comПрограмма представляет собой набор модулей — самостоятельных единиц компиляции, которые могут компилироваться раздельно.
При этом программныймодуль может быть (но не обязан) разделён на две части: модуль определений и модуль реализации. Модуль определений — это внешний интерфейс модуля, тоесть набор экспортируемых им имён констант, переменных, типов, заголовков процедур и функций, которые доступны внешним модулям. Модуль реализациисодержит программный код, в частности, конкретизацию описаний всего, что перечислено в модуле определений. Например, некоторый тип «запись» может бытьобъявлен в модуле определений с указанием лишь его имени, а в модуле реализации — с полной структурой.
В этом случае внешние модули могут создаватьзначения данного типа, вызывать процедуры и функции, работающ ие с ним, выполнять присваивание переменных, но не имеют прямого доступа к структурезначений, поскольку эта структура не описана в модуле определений. Если для этого же типа описать в модуле определений структуру, то она станет доступна.Помимо модулей глобального уровня в Модуле-2 допускается создавать локальные модули.Импорт определений, описанных в прочих модулях, полностью контролируется. Можно импортировать модули определений целиком, но синтаксис позволяетсущ ественно уточнять списки импорта, например, импортировать из модуля конкретные константы, переменные, процедуры и функции, только те, которыенеобходимы.DEFINITION MODULE ModuleName;{Import}{Declaration}END ModuleName.========================Где Import это:[FROM ModuleName] IMPORTidentifier {,identifier};IMPLEMENTATION MODULE ModName;{Import}{Declaration}[ BEGINListOfStatements[EXCEPTListOfStatements][FINALLYListOfStatementsEXCEPTListOfStatements]]END ModName.(* Модуль определений *)(* Модуль реализаций *)MODULE ModName; (* Должен существовать единственный на весь проект.
Это main. *){Import}{Declaration}BEGINListOfStatements[EXCEPTListOfStatements]END ModName.Для обеспечения видимости в других модулях объявления функций, переменных и типов, описанные в модулях определений, можно импортировать.Остановимся на типах. При импортировании их внутренняя структура становится видна импортирующ ему модулю (т.н. прозрачный экспорт). Сущ ествует скрытыйэкспорт (opaque export), где видно становится только имя типа. Он возможен только для указательного типа (но сделаем указатель на структуру - и вуаля,получим инкапсуляцию и абстракцию данных).ADA[править]Ада, наверное - единственный язык со вложенностью модулей, их раздельной компиляцией и двойной связью одновременно.
Опишем вложеннуюспецификацию, тут ничего сложного:open in browser PRO versionAre you a developer? Try out the HTML to PDF APIpdfcrowd.compackage Outer is...procedure some_proc (X: Some_type) is private;package Inner is... -- Тут, в общем то видно все, что есть в пакете Outer.end Inner;...end Outer;Тела этих пакетов, как и тело функции, можно разнести по разным файлам (единицам компиляции), используя "заглушку" separate:package body Outer is...package Inner is separate;...procedure some_proc (X: some_type) is separate;end Outer;Теперь опишем тела модуля Inner и процедуры.separate (Outer) --Тут нет `;'package body Inner is...end Inner;separate (Outer)procedure some_proc (X: some_type) is...end some_proc;Вот здесь заглушка separate и является двойной модульной связью.Исключительные ситуации и обработка ошибок[править]ЗачечаниеКроме перечисленных в итоговой таблице языков исключения поддерживает Visual Basic.Исключения и блоки try {} catch {} finally {}.
Семантика возобновления и семантика завершения.[править]Семантика возобновления: после обработки исключения управление может вернуться непосредственно в точку, где возникло исключение (варианты: наследующ ий оператор или на любой оператор из того же блока). Пример языка c семантикой возобновления: Visual Basic.Моделирование семантики возобновления на C++:bool need_restart = true;while (need_restart) {need_restart = false;try {// Some code here} catch (...) {// C# - просто catch, без круглых скобок// Java - catch (Throwable e)}}open in browser PRO versionneed_restart = true;Are you a developer? Try out the HTML to PDF APIpdfcrowd.comСемантика завершения: после возникновения исключения блок, в котором оно возникло, обязательно завершается. Обработка исключения происходит вблоках, вызвавших блок с исключением.
Пример языка с семантикой завершения: Си++.catch (в delphi - except) - то что будет выполнено в случае ошибки в блоке try. finally - то что будет выполнено в любом случае, вне зависимости от того чтопроизошло в блоке try.Конструкция try ... finally ... есть в C#, Java, Delphi. Декларируется, что в C++ в finally нет необходимости в виду RAII и, как следствие, выполнении деструкторовна выходе из блока.throw (C++) и throws (Java)[править]Текст раздела построен с т.з. программиста Java (иначе говоря, обозначены отличия синтаксиса и семантики конструкции C++ от конструкции Java, а не наоборот).Причина — одно из заданий экзамена по ЯПам звучит примерно как «опишите конструкцию throws в Java (зачем нужно и как работает).
Как моделируется на C++,Delphi[7]?».Примеры употребления конструкций:// Javavoid someMethod() throws IOException, SomeOtherException { … }// IOException — стандартный класс исключения, наследник Exception.// SomeException должен быть наследником Throwable.void someMethod() { … }// Запись «не выбрасывает исключения»: отсутствие throws и списка исключений.// C++void someMethod() throw (SomeException1, SomeException2) { … }// SomeException1, SomeException2 — вообще говоря, любые типы.// Декларациии throw должны совпадать как при определении, так и при описании.void someMethod() throw () { … }// Запись «не выбрасывает исключения»: throw ().void someMethod() { … }// Может выбрасывать любые исключения.Данные конструкции служат для того, чтобы показать программисту и компилятору, что данный метод (или, в случае C++, метод или функция) может выбрасыватьисключения соответствующ их типов.
Насколько я понимаю, всё это влияет только на статические проверки компилятора и эстетические чувства программиста. Вruntime эти декларации никак себя не проявляют, поэтому употребляемые здесь «может / не может выбрасывать исключение данного типа» и тому подобныеобороты следует понимать в контексте статических проверок. (Замечание: не совсем верно.
Исключения могут возникнуть в виртуальной функции или вотдельно оттранслированной. Memento std::unexpected().)В Java считается, что метод, выбрасывающ ий исключение должен обозначить это с помощ ью конструкции throws. Иначе говоря, считается, что если директивыthrows нет, то метод не выбрасывает исключений. Компилятор делает некоторые статические проверки, по крайней мере, запрещ ает выбрасывать исключения, неперечисленные в throws, явно — с помощ ью оператора throw.В C++, в отличие от Java, если директива throw не задана, то считается, что данный метод или функция может выбрасывать любые исключения.
Статические(времени компиляции) проверки делаются только для тех методов/функций, для которых указан (возможно пустой) список исключений.Одно из заданий экзамена по ЯПам[править]2004 г, задание 8. Смоделируйте на языке Си++ функциюopen in browser PRO versionAre you a developer? Try out the HTML to PDF APIpdfcrowd.comvoid f() throw (E1,E2,E3) { g(); h(); }предполагая, что конструкция throw[8] не допускается компилятором.void f(){try {g(); h();} catch (E1) {throw;} catch (E2) {throw;} catch (E3) {throw;} catch (...) {unexpected();}}ADA[править]Создание исключения:New_Exception: exception;Поднятие/возбуждение исключения[9]:raise New_Exception;Отлов исключения:beginRise_Exception;exceptionwhen New_Exception =>Do_Smth;end;Отлов исключения так же может иметь такой вид:when Error: Error_Name =>Однако, что он означает я до конца не понял, но на экзамене это вряд ли нужно будет.