Ada (798525), страница 19
Текст из файла (страница 19)
. .и типы:type Color is (red, green, blue);type Mix is array (Color range <> ) of Boolean;type Option is array (Color) of Boolean;тогда, Mix может соответствовать Vector, а Option может соответствовать Table.package R is new P( Item=> Boolean,Index => Color,Vector => Mix,Table=> Option);9.2.2 Параметры-значенияПараметры-значения позволяют указывать значения для переменных внутри настраиваемогомодуля:generictype Element is private;Size: Positive := 200;package Stacks isprocedure Push...procedure Pop...function Empty return Boolean;end Stacks;package body Stacks isSize : Integer;theStack : array(1..Size) of Element;.
. .Тогда, создать экземпляр настраиваемого модуля можно одним из следующих способов:package Fred is new Stacks(Element => Integer, Size => 50);package Fred is new Stacks(Integer, 1000);package Fred is new Stacks(Integer);Следует обратить внимание на то, что при конкретизации настраиваемого модуля фактическийпараметр-значение должен быть обязательно указан только в случаях когда для формальногопараметра-значения не представлено значение по-умолчанию.В качестве параметров-значений допускается использование строк.generictype Element is private;File_Name : String;package ....Примечательно, что параметр File_Name, имеющий строковый тип String, - не ограничен(not constrained).
Это идентично строковым параметрам для подпрограмм.9.2.3 Параметры-подпрограммыВ качестве параметра настройки для настраиваемого модуля может быть переданаподпрограмма. Необходимость в параметрах-подпрограммах чаще всего возникает когда какойлибо формальный параметр-тип настраиваемого модуля описан как приватный илилимитированный приватный тип.
В таких случаях, Ада накладывает традиционные ограниченияна использование операций над экземплярами данного типа внутри тела настраиваемого модуля.Однако, при этом может возникнуть необходимость в осуществлении сравнения или выполненияпроверки на равенство значений данного типа, внутри тела настраиваемого модуля.Следовательно, параметры-подпрограммы являются механизмом, который предоставляет длякомпилятора информацию о том как осуществлять эти действия.В качестве примера рассмотрим типичный случай требующий применение параметровподпрограмм. Предположим, что в качестве одного из параметров настраиваемого модуляиспользуется лимитированый приватный тип. Тогда, для этого лимитированного приватноготипа, с помощью параметров-подпрограмм, можно осуществить передачу операций: проверка наравенство и присваивание.generictype Element is limited private;with function "="(E1, E2 : Element) return Boolean;with procedure Assign(E1, E2 : Element);package Stuff is .
. .Конкретизация такого настраиваемого модуля может иметь вид:package Things is new Stuff(Person, Text."=", Text.Assign);Для формального параметра-подпрограммы может быть указана подпрограмма используемая поумолчанию. Тогда, при конкретизации настраиваемого модуля, фактический параметрподпрограмма может не указываться. Предположим, что у нас есть подпрограмма,спецификация которой имеет вид:procedure My_Assign(E1, E2 : Person);Тогда, при описании формального параметра-подпрограммы Assign, мы можем указатьпроцедуру My_Assign как подпрограмму которую необходимо использовать по-умолчаниюследующим образом:generictype Element is limited private;with function "="(E1, E2 : Element) return Boolean;with procedure Assign(E1, E2 : Element) is My_Assign(E1, E2 : Person);package Stuff is . .
.В результате, конкретизация настраиваемого модуля, с использованием подпрограммы заданнойпо-умолчанию, может иметь следующий вид:package Things is new Stuff(Person, Text."=");И наконец, при описании спецификации формального параметра-подпрограммы, можно указать,что выбор процедуры по-умолчанию должен осуществляться согласно традиционных правилвыбора подпрограмм. Для функции, реализующей действие знака проверки на равенство ("=")мы можем указать это следующим образом:generictype Element is limited private;with function "="(E1, E2 : Element ) return Boolean is <>;. . .Теперь, если при конкретизации настраиваемого модуля для функции "=" не будет представленасоответствующая функция, то будет использоваться функция проверки на равенство поумолчанию, выбранная в соответствии с фактическим типом Element. Например, еслифактический тип Element - тип Integer, то будет использоваться обычная, для типаInteger, функция "=".9.3 Преимущества и недостатки настраиваемых модулейВ заключение обсуждения настраиваемых модулей Ады необходимо отметить преимущества инедостатки использования данной концепции.Основным преимуществом использования настраиваемых модулей является то, что ониоказывают значительное содействие в многократном повторном использовании ранееразработанных и отлаженных алгоритмов.
Действительно, настраиваемые модули позволяютразработчику однажды написать и отладить алгоритмы подпрограмм для обработки объектовтип которых в последствии будет указываться пользователями этих подпрограмм.Однако, применение настраиваемых модулей не лишено недостатков. Разработка алгоритмовдля настраиваемых модулей требует более тщательного внимания, что в результате являетсядополнительной нагрузкой для их автора. Также необходимо заметить, что реализациянастраиваемой процедуры, функции или пакета может оказаться не столь эффективной какнепосредственная реализация.
Компилятор может генерировать один и тот же код для всехэкземпляров настроенных процедур, функций или пакетов, не зависимо от фактическиобрабатываемых данных.10. ИсключенияКак это не печально, но процесс разработки и эксплуатации любого программного обеспечениявсегда сочетается с процессом поиска и исправления ошибок. Все ошибки, возникающие впрограммах на языке Ада, можно разделить на два класса:- ошибки, которые обнаруживаются на этапе компиляции программы- ошибки, которые обнаруживаются во время выполнения программыТаким образом, не смотря на то, что одной из целей при разработке Ады была задачамаксимально обеспечить возможность ранней диагностики и обнаружения ошибок, то естьобнаружение ошибок на стадии компиляции программы, бывают случаи когда ошибкивозникают и во время выполнения программы.В Аде, ошибочные или другие исключительные ситуации, возникающие в процессе выполненияпрограммы, называются исключениями.
Это значит, что при возникновении ошибочнойситуации, во время выполнения программы, вырабатывается сигнал о наличии исключения.Такое действие называют возбуждением (генерацией или порождением) исключения ипонимают как приостановку нормального выполнения программы для обработкисоответствующей ошибочной ситуации. В свою очередь, обработка исключения - этовыполнение соответствующего кода для определения причины возникновения ошибочнойситуации которая привела к возбуждению исключения, а также, при возможности, устранениепричины возникновения ошибки и/или выполнение других корректирующих действий.Примечательно, что идея использования механизма исключений - это тема многих споров о том,что исключения являются или путем "ленивого" программирования, без достаточного анализапроблем и сопутствующих условий приводящих к возникновениям ошибок, или обычным видомуправляющих структур, которые могут быть использованы для достижения некоторых эффектов.Тем не менее, хотя эти споры не прекращаются и в настоящее время, следует обратить вниманиена то, что механизм исключений благополучно заимствован некоторыми современнымиреализациями других языков программирования (например, широко известная реализация языкаObject Pascal фирмы Borland).Все исключения языка программирования Ада можно разделитьпредопределенные исключения и исключения определяемые пользователем.настандартно10.1 Предопределенные исключенияСуществует пять исключений которые стандартно предопределены в языке программированияАда:Constraint_ErrorNumeric_ErrorProgram_ErrorStorage_ErrorTasking_Error-Ошибка ограниченияОшибка числаОшибка программыОшибка памятиОшибка задачи10.1.1 Исключение Constraint_ErrorИсключение Constraint_Error возбуждается в следующих случаях:•••при попытке нарушения ограничения диапазона, ограничения индекса или ограничениядискриминантапри попытке использования компонента записи, не существующего при текущемзначении дискриминантапри попытке использования именуемого или индексируемого компонента, отрезка илиатрибута объекта, обозначенных ссылочным значением, если этот объект не существует,поскольку ссылочное значение равно nullРассмотрим пример:procedure Constraint_Demo isX : Integer range 1..20;Y : Integer;beginPut("enter a number ");Get(Y);X := Y;Put("thank you");end Constraint_Demo;Если пользователь вводит значение выходящее за диапазон значаний 1..20, то нарушаетсяограничение диапазона значений для X, и происходит исключение Constraint_Error.
Поскольку вэтом примере не предусмотрен код, который будет обрабатывать это исключение, то выполнениепрограммы будет завершено, и окружение времени выполнения Ады (Ада-система)проинформирует пользователя о возникшей ошибке. При этом, строкаPut("thank you");выполнена не будет. Таким образом, при возникновении исключения, остаток, выполняющегосяв текущий момент блока, будет отброшен.Рассмотрим пример в котором выполняется нарушение ограничения диапазона индексныхзначений для массива:procedure Constraint_Demo2 isX : array (1..5) of Integer := (1, 2, 3, 4, 5);Y : Integer := 6;beginX(Y) := 37;end Constraint_Demo2;Здесь, исключение Constraint_Error будет генерироваться когда мы будем пытаться обратиться кнесуществующему индексу массива.10.1.2 Исключение Numeric_ErrorИсключение Numeric_Error возбуждается в случае когда предопределенная численная операцияне может предоставить математически корректный результат Это может произойти приарифметическом переполнении, делении на нуль, а также не возможности обеспечитьтребуемую точность при выполнении операций с плавающей точкой.