Ada (798525), страница 5
Текст из файла (страница 5)
Вещественные числа не могут считаться дискретнымипоскольку между двумя любыми вещественными числами располагается бесконечноемножество вещественных чисел (естественно, теоретически).2.5.2 Предопределенный логический тип BooleanВ Аде, предопределенный логический тип Boolean описывается как перечислимый тип впакете Standard:typeBooleanis(False, True);Таким образом, переменные логического типа Boolean могут принимать только одно из двухзначений: True (истина) или False (ложь).Примечательно, что предопределеннный логический тип Boolean имеет специальноепредназначение. Значения этого типа используются в условных инструкциях языка Ада("if ...
", "exit when ... ", ...). Это подразумевает, что если вы пытаетесь описать свойсобственный логический тип Boolean, и описываете его точно также как и предопределенныйтип Boolean (полное имя предопределенного логического типа - Standard.Boolean), то выполучаете абсолютно самостоятельный тип(!). В результате, вы не можете использоватьзначения, описанного вами типа Boolean, в условных инструкциях языка Ада, которыеожидают только тип Standard.Boolean.Значения предопределенного логического типа Standard.Boolean возвращают знакиопераций сравнения:=/=<<=>>=-------равноне равноменьшеменьше или равнобольшебольше или равноДля обработки значений типа Boolean могут быть использованы следующие знаки операций:andand then-- логическое И:-- логическое И:--oror elsexornotрезультат вычисления левой части - True-- логическое ИЛИ:-- логическое ИЛИ:--вычисляются и левая, и правая часть выраженияправая часть выражения вычисляется, есливычисляются и левая, и правая часть выраженияправая часть выражения вычисляется, еслирезультат вычисления левой части - False-- исключающее ИЛИ-- отрицание (инверсия); унарная операцияОбычно, при вычислении значений логических выражений, компилятор сам определяетпоследовательность вычисления каждого логического значения.
При этом, производитсявычисление всех логических переменных, указанных в логическом выражении. Тем кто знаком сязыком Паскаль следует заметить, что такой подход отличается от правил принятых всовременных диалектах Паскаля, где, для повышения производительности, определениезначения результата всего логического выражения может быть выполнено сокращенно, взависимости от предварительных результатов обработки выражения. Например, приопределении значения результата следующего логического выражения(B /= 0) and (A/B > 0)в случае, когда значение B равно нулю будет возникать ошибка деления на ноль.
Причина в том,что значение части выражения, расположенной справа от "and", вычисляется всегда, независимо от значения результата полученного при вычислении (B /= 0).Чтобы избежать подобных ошибок, а также в целях увеличения производительности,необходимо производить вычисление значений логических переменных в определеннойпоследовательности и прекращать ее как только результат всего выражения уже определен. Дляэтого можно использовать "and then" вместо "and", и "or else" вместо "else", указываяпорядок обработки логического выражения явно:(B /= 0) and then (A/B > 0)В этом случае, обработка выражения справа от "and then" будет производиться только вслучае когда B не равно нулю, т.е. результат слева от "and then" - True.Можно переписать предыдущий пример с использованием "or else".
Тогда, обработкалогического выражения будет завершена в случае если значение слева от "or else" вычисленокак True:(B = 0) or else (A/B <= 0)В заключение обсуждения логического типа отметим, что Ада не позволяет одновременноеиспользование "and" ("and" или "and then"), "or" ("or" или "or else") и "xor" в одномвыражении не разделенном скобками. Это уменьшает вероятность разночтения содержимогосложного логического выражения. Например:(A < B) and (B > C) or (D < E)((A < B) and (B > C)) or (D < E)-- запрещено-- разрешено2.5.3 Символьные типы Ады (Character, Wide_Character)Ада имеет два предопределенных перечислимый типа, Character и Wide_Character, дляподдержки обработки символьных значений. Согласно стандарта, любой перичислимый типкоторый содержит хотя бы один символьный литерал является символьным типом.Оригинальный стандарт Ada83 описывал 7-битный тип Character.
Еще до появлениястандарта Ada95, это ограничение было ослаблено, но оставалось принудительным для старыхкомпиляторов (например таких как компилятор Meridian Ada). Это создавало трудности припопытках отобразить графические символы на PC, поскольку для отображения символов скодами большими чем ASCII-127 приходилось использовать целые числа. Такая поддержкаобеспечивалась за счет специальных подпрограмм предоставляемых разработчикамисоответствующего компилятора.В настоящее время, предопределенный символьный тип Character предусматривает 256различных символьных значений (то есть, является 8-битным), и основывается на стандартеISO-8859-1 (Latin-1).Некоторые символы не имеют непосредственно печатаемого значения (первые 32 символа).Такие символы используются в качестве управляющих (примером может служить символ CR возврат каретки).
Для обращения к таким символам можно использовать пакет ASCII, которыйявляется дочерним пакетом пакета Standard (благодаря этому, нет необходимости указыватьпакет ASCII в спецификаторах контекста with и/или use). Например, для обращения к символувозврат каретки можно использовать: ASCII.CR. Однако, пакет ASCII содержит только первые128 символов и считается устаревшим, и возможно, что в будущем он будет удален.
Поэтому,вместо старого пакета ASCII рекомендуется использовать пакет Ada.Characters.Latin_1, которыйпредоставляет 256 символов. Следовательно, используя пакет Ada.Characters.Latin_1, к символувозврата каретки можно обратиться следующим образом: Ada.Characters.Latin_1.CR.Предопределенный символьный тип Wide_Character основывается на стандарте ISO-10646Basic Multilingual Plane (BMP) и предусматривает 65336 различных символьных значений(использует 16 бит).Также, Ада предоставляет пакет Ada.Characters.Handling, предлагающий набор полезныхподпрограмм символьной обработки.Система компилятора GNAT предоставляет дополнительный пакет Ada.Characters.Wide_Latin_1,который описывает символьные значения типа Wide_Character соответствующие кодировкеLatin_1.Таким образом, для работы с символьными значениями, в Аде представлены следующие пакеты:Standard.ASCII-- предоставляет только первые 128 символов-- (считается устаревшим)Ada.CharactersAda.Characters.Latin_1Ada.Characters.Handling--- предоставляет 256 символов ISO-8859-1 (Latin-1)-- предоставляет подпрограммы символьной обработкиAda.Characters.Wide_Latin_1-- дополнительный пакет из поставки-- системы компилятора GNATСледует заметить, что пакет ASCII считается устаревшим и его не рекомендуется использоватьпри написании новых программ.
Вместо него необходимо использовать стандартный пакетAda.Characters.Latin_1.Также следует заметить, что стандарт не требует полноценного обеспечения поддержкинациональных кодировок, которые отличны от кодировки Latin-1. Возможность предоставлениятакой поддержки возлагается на разработчиков соответствующего компилятора. Другимисловами, в настоящее время, обеспечение поддержки кириллических кодировок нерегламентируется стандартом.2.6 Типы и подтипыКак уже говорилось, концепция типа является в Аде основопологающим фактором созданиянадежного программного обеспечения.
Предположим, что у нас есть два целочисленных типа,которые как-то характеризуют "звоночки" и "свисточки", и мы никак не хотим смешивать этипонятия. Нам необходимо, чтобы компилятор имел возможность предупредить нас: "Ба, да выпытаетесь смешать выши "звоночки" и "свисточки"! Что Вы в действительностиподразумеваете?". Это выглядит излишними осложнениями для людей, которые используютдругие языки программирования со слабой типизацией данных. Размышления над тем какиеданные необходимо представить, описание различных типов данных и правил конвертированиятипов требуют некоторых усилий.
Однако, такие усилия оправдываются тем, что как только этосделано, компилятор сможет помочь отыскать разные глупые ошибки.Бывают случаи, когда нам необходимо указать, что какие-то переменные могут хранить толькокакое-то ограниченное число значений предоставляемых определенным типом данных. Приэтом, мы не хотим описывать самостоятельный новый тип данных, поскольку это потребуетявного указания правила преобразования типа при взаимодействии со значениями, которыеимеют оригинальный тип данных, то есть нам необходима возможность смешивать различныетипы, которые, по своей сути, являются одинаковыми сущностями, но при этом имеютнекоторые различия в своих характеристиках.
К тому же, мы хотим сохранить преимуществапроверки корректности наших действий, которые предоставляет компилятор. В таких случаях,Ада позволяет нам описывать подтипы (subtype) существующих типов данных (этосоответствует типам определяемым пользователем в Паскале).Общий синтаксис объявления подтипа имеет вид:subtype Name_1 is Base_Type;-- в данном случае, Name_1 является-- синонимом типа Base_Typesubtype Name_2 is Base_Type range Lowerbound..Upperbound;Примеры объявления подтипов приводятся ниже:type Processors is (M68000, i8086, i80386, M68030, Pentium, PowerPC);subtype Old_Processors is Processors range M68000..i8086;subtype New_Processors is Processors range Pentium..PowerPC;subtypesubtypesubtypesubtypeData is Integer;Age is Data range 0..140;Temperatures is Float range -50.0..200.0;Upper_Chars is Character range 'A'..'Z';Подтип, по своей сути, является той же самой сущностью, что и оригинальный тип, но при этомон может иметь ограниченный диапазон значений оригинального типа.
Значения подтипа могутиспользоваться везде, где могут использоваться значения оригинального типа, а также значениядругих подтипов этого оригинального типа При этом, любая попытка присваивания переменнойтакого подтипа значения выходящего за границы указанного для этого подтипа диапазонадопустимых значений будет приводить к исключительной ситуации Constraint_Error (прощеговоря - ошибке программы). Такой подход облегчает обнаружение ошибок, а также, позволяетотделить обработку ошибок от основного алгоритма программы.My_AgeHeight: Age;: Integer;Height := My_Age;-- глупо, но никогда не вызывает проблемMy_Age := Height;-- может вызвать проблемы, когда значение типа Height-- будет за пределами диапазона значений My_Age (0..140),-- но при этом остается совметимымЧтобы избежать генерацию исключительной ситуации, можно использовать проверкипринадлежности диапазону ("in" и/или "not in").
Например:I : Integer;N : Natural;...ifI in NaturalthenN := IelsePut_Line ("I can't be assigned to N!");end if;. . .Реально, все типы Ады являются подтипами анонимных типов, рассматриваемых как ихбазовые типы. Поскольку базовые типы анонимны, то на них нельзя ссылаться по имени. Приэтом, для получения базового типа можно использовать атрибут 'Base. Например,Integer'Base - это базовый тип для Integer. Базовые типы могут иметь или могут не иметьдиапазон значений больший чем их подтипы.