Н. Джехани - Язык Ада (1988) (1160771), страница 50
Текст из файла (страница 50)
Вторая программа показывает, как определенный пользователем генератор может быть легко написан на языке Ада. Эту программу распределения памяти невозможно (или крайне трудно) написать на языках со строгой типизацией, таких как Паскаль, которые не обладают возможностями обойти механизм строгой типизации. 8.10.1. Печать ввода и вывода Задача состоит в том, чтобы написать пакет Тх'РЕ%К1ТЕК для ЭВМ РОР-11, который дает пользователю (более точно, системному программисту) процедуры для чтения символов с клавиатуры консоли и их распечатки на печатающем устройстве '!. Необходимые спецификации устройств следующие: Адрес аппаратного буфера клавиатуры 8 № 177562 № Адрес прерывания от клавиатуры 8 № 60 № Адрес аппаратного буфера печатающего устройства 8 № 177566 № Адрес прерывания печатающего устройства 8 № 64 № Приоритет прерывания 4 Прерывание от клавиатуры возникает после того, как в аппаратный буфер поступает новый символ з!.
Прерывание печатающего устройства возникает после того, как напечатан помещенный в буфер символ. Одну задачу-драйвер определим для клавиш консоли, а другую — для печатающего устройства. Драйвер для клавиш будет иметь внутренний буфер на 64 символа, и он может принимать символы до тех пор, пока буфер не полон. Из этого буфера пользователь может читать символы, используя для этого процедуру КЕА[э СНАК. Драйвер печатающего устройства имеет аналогичную структуру.
Спецификация пакета ТУРЕ%!к[ТЕК имеет вид вас[гайе Т у'РЕ%К[ТЕ[(!а ргосее[пге [(ЕА[) СНА[к(С: он! СНА[кАСТЕК); руссе)иге %[к!ТЕ СНАК(С: 1п СНА[(АСТЕК); епв Т у'РЕ%[к!ТЕК; и Эта задача является адаптапией примера из [уу!К77а1. " В аппаратном буфере перед получением нового символа старый следует восстановить. В противном случае первый символ будет потерян. Будет считать, что задача чтения символов из аппаратного буфера должна отвечать требованиям скорости, чтобы не потерять какой-нибудь символ.
Это следствие из правил приоритета, по которым в первую очередь выполняется оператор принятия прерывания, как имеюгдий более высокий приоритет по сравнению с обычным вызовом входа. Главе В Тело этого пакета имеет вид раейайе Ьоду ТУРЕ%К!ТЕК 1в !авй КЕУВОАК0 !в ргарва РК1ОК1ТУ(4); -- должны иметь по крайней мере приоритет прерывания епггу ОЕТ(С: оп! СНАКАСТЕК); епиу Рс1Т; Гог Р()Т пве а! 8№60№; епо КЕУВОАК0; !ав1г РК1ХТЕК!в ргарпа РК)ОК1ТУ(4); -- должны иметь по крайней мере приоритет прерывания епггу ОЕТ; еп(гу РОТ(С: !п СНАКАСТЕК); Гог ОЕТ пве а! 8№64№; епй РКГХТЕК; ргоееоаге КЕА0 СНАК(С: оаг СНАКАСТЕК) 1в Ье81п КЕУВОАК0.ОЕТ(С); епа КЕА0 СНАК; ргоееопге 9~К!ТЕ СНАК(С: !п СНАКАСТЕК) 1в Ьей!п РК1ХТЕК.РОТ(С); епо Уг'К!ТЕ СНАК; !аеас )ни!у КЕУВОАК0!в зерага!е; !авй !нн)у РК1ХТЕК !в верагаге; еао ТУРЕ%К!ТЕК; Тела задач КЕУВОАК0 и РК1ХТЕК, следы которых указаны в пакете ТУРЕ%К1ТЕК, имеют вид керогазе(ТУРЕ йгК1ТЕК) гавй Ьоду КЕУВОАК0 гв МАХ: еоавгап(: 64; -- внутренний размер буфера А: аггау(1..МАХ) оГ СНАКАСТЕК; -- внутренний буфер 1ХВ, ООТВ: 1ХТЕОЕК: 1; -- указатели буфера Х: 1ХТЕОЕК: Рй -- буферный счетчик НАК0%АКЕ В()РЕЕК: СНАКАСТЕК; Гог НАК0%гАКЕ ВНРРЕК пве ав 8№177562№; 249 Спа ификато ы представления и особенности, зависящие от ализации Ьеп!п 1оор ве!ес! пЬеп1Ч > О > ассер! ОЕТ(С: ов! СНАКАСТЕК) до С: А(013ТВ); епо ОЕТ; ОБТВ: 013ТВ пин) МАХ + 1; 1Ч: )ч — 1; ог пЬеп)ч( < МАХ > ассар! Р()Т по А(1ХВ): НАКО%АКЕ В13РРЕК; епо Р1/Т„ 1)ч(В: 1ХВ птоо МАХ + 1; )ч): )ч) + 1; ее$ ве!ес1; епб !оор; епо' КЕ г'ВОАК(т; зерага!е(Т зтРЕ%К1ТЕК) !пвЬ Ье$у РК1НТЕК 1в МАХ; сопя!апв; 64; -- внУтРенний РазмеР бУфеРа А: актау(1..МАХ) о1 СНАКАСТЕК; — - внутренний бУФеР 1НВ, 013ТВ: 1)ч!ТЕОЕК: 1; - — указатели буфера Н: 1НТЕОЕК: О; -- буферный счетчик НАК1)%АКЕ ВБРГЕК: СНАКАСТЕК; 1ог НАК0%АКЕ В()ГРЕК пве а! 8№177566№; НАК0%АКЕ В()РЕЕК ЕМРТУ: ВОО(.ЕА)ч): ТЛЕ; Ьеп)п 1оор ве)есг ассер! ОЕТ; -- печатаемый символ !1Н > 0 гЬеп НАК0%АКЕ ВОРРЕК: А(О()ТВ); ООТВ: ООТВ птоо МАХ + 1; Н: Н вЂ” 1; е)ве НАК()%АКЕ В()РЕЕК ЕМРТ'(т: ТЮЗЕ; епо тЕ ог юЬеп т! < МАХ > ассер! Р(ЗТ(С: 1п СНАКАСТЕК) по А(ПЧВ): С; Глава В енз$ РОТ; 1ХВ: 1ХВ вое$ МАХ + 1; Х: Х+1; $1 НАК(з'зЧАКЕ В$.)РЕЕК ЕМРТУ $$геп НАК$)ЖАКЕ ВОРРЕК: А(О()ТВ); О()ТВ: 0$)ТВ воз! МАХ + 1; Х: Х вЂ” 1; НАКР%~АКЕ В()РЕЕК ЕМРТУ: РА).БЕ; ено $Е ене$ ве$есй ене$ $оор; евз$ РК!ХТЕК; Задачи, описанные в пакете ТУРЕТЧК1ТЕК, однажды активизированные, могут быть завершены только аварийно.
8.10.2. Генерапвр памяти Необходимо написать генератор памяти общего назначения А$.$.ОСАТЕ, подобный генератору нету в языке Ада. Предполагается, что зависящий от реализации пакет БУБТЕМ (он описан в предопределенном пакете БТАХОАКО) содержит процедуру МОКЕ-МЕМОКУ, которая распределяет «сырую» (необычную) память 'з. Процедура МОКЕ МЕМОКУ имеет спецификацию ргосее$вге МОКЕ МЕМОКУ(Х: $в 1ХТЕОЕК; А$ПЖ: ов! 1ХТЕОЕК); где Х вЂ” число битов, которые необходимо распределить, а А(ЮК вЂ” адрес первого кванта памяти (байтов или слов) распределяемой памяти. Будет распределено целое число квантов памяти, содержащих по крайней мере Х бит. А(з(зК имеет тип 1ХТЕОЕК, и его необходимо преобразовать к тому ссылочному типу, для которого распределяется память, причем это должно согласовываться с правилами строгой типизации языка Ада. Это преобразование осуществляется с использованием настраиваемой функции ОХСНЕСКЕ(г СОХЧЕКЯ10Х.
А$. ОСАТЕ опишем как настраиваемую процедуру с настраиваемыми формальными параметрами — ссылочным типом РТ и типом объектов Т, на которые указывают переменные типа РТ. Спецификация АЫ.ОСАТЕ имеет внд зг!$$з ОХСНЕСКЕ)З СОХЧЕКВ1ОХ; йенепс (уре Т $й Ввз)гез$ рпгаее; (уре РТ $в рг)уаее; — определение объектов типа Т ргосез$вге А1Л.ОСАТЕ(Х: оц! РТ); "Написание АП.ОСАТЕ зависит от возможностей, которые представляет реализация языка Ада для связи с аппаратурой. Например, вместо процедуры МОКЕ МЕМОКу пакет ЯТЗТЕМ может содержать константы, указываюшие на верхнюю н нижнюю границы для памяти, которая может использоваться для определенного пользователем распределения памяти. В этом случае процедура, аналогичная процедуре МОКЕ МЕМОКУ, должна быть написана пользователем.
Сие инат ы и ставлвния н особенности, завися ие от алиев ии Тело процедуры АЬЬОСАТЕ имеет аид ртоседпте АЬЬОСАТЕ(Х: оп1 РТ) 1в А: 1ХТЕОЕК; -- будет содержать целое значение адреса 1ппе~юп СОХЧЕКТ 1е пете (ЗХСНЕСКЕ1) СОХЧЕК81ОХ(1ХТЕОЕК, РТ); пве БУБТЕМ; Ьефп МОВЕ МЕМОКУ1Т'31УЕ, А); Х: СОХЧЕКТ(А); еп4 АЬЬОСАТЕ; Приложение Пошаговая разработка программ ~ОЕН8Ц ') 1.
Некоторые требования к хорошей методологии программирования Методология программирования призвана: 1) помогать программисту управлять сложностью решаемой задачи и давать руководящие указания для формулирования решения задачи; 2) требовать от программиста соблюдения правил записи процесса разработки программ. Эту программную разработку могут затем читать другие программисты, оценить ее и подвергнуть конструктивной критике; 3) помогать создавать понимаемые программы; 4) приводить к программам, правильность которых может быть доказана. Если доказательство правильности слишком сложно, методология должна предоставлять систематический подход к тестированию программ; 5) быть общепринменимой, а не ограничиваться одним классом задач; 6) помогать в создании высокоэффективных программ; 7) позволять создавать программы, котоыре можно легко модифицировать.
2. Пошаговая разработка программ Пошаговая разработка — это нисходящий метод проектирования программ (впервые был описан Виртом 1%1К71]), удовлетворяющий перечисленным выше критериям. Вирт дал систематическую формулировку и описание этого метода, которому программисты ранее следовали интуитивно. Этот метод считается многими специалист.ами в области информатики самой важной формализацией в программировании 70-х годов ]вйо75]. Данный подход применим не только к проектированию программ, но и к проектированию сложных систем. Прн нисходящем подходе решаемая задача детализируется, или декомпозируется, на ряд подзадач, которые затем необходимо решить. Декомпозиция, или детализация, должна быть такой, чтобы 1) подзадачи были разрешимыми; 2) подзадачи были разрешимы по возможности с наименьшим влиянием друг на друга; 3) решение каждой подзадачи требовало меньше усилий, чем первоначальная задача; 4) если подзадачи решены, то решение всей задачи не должно требовать существенных дополнительных усилий.
Процесс декомпозиции распространяется и на подзадачи. Конечно, если решение проблемы очевидно или тривиально, нет необходимости прибегать к декомпозиции. " ГсЭЛпзегзсап Те!ерьопе апд Те!авгарь Сопзрапу. Выбранные огрыакн ненаташтсн с разрешения.
Пошамввя раа вбогав я г амм 253 Если Ро — это начальная формулировка/решение задачи, то конечная формулировка/решение этой же задачи Р, (выполняемая программа) получается после серии последовательных шагов детализации. Детализация Р;,1 получается из Р; путем внесения дополнительных подробностей в формулировку/решение задачи Р; Детализации Рв, ..., Р„представляют собой различные уровни абстракции, Так, Ро может выражать наиболее абстрактную версию решения задачи Р„, в то время как Р„представляет детальный вариант решения задачи Ра. Каждая детализация Р; состоит из последовательности операторов и описаний данных Рд Ргш На каждом шаге детализации вносятся дополнительные подробности о реализации каждого Р,. Процесс детализации заканчивается, когда все операторы можно либо непосредственно выполнить на машине, либо их легко оттранслировать в выполняемые машиной команды.
3. Рекомендации по детализации Пошаговая детализация является итеративным процессом. Если полученное решение не является окончательным, то процесс детализации повторяется с использованием дополнительных сведений, полученных на предыдущих шагах. При решении больших или сложных задач могут потребоваться дополнительные итерации, прежде чем программист удовлетворит всем требованиям правильности, элегантности и эффективности решения. Приведем некоторые рекомендации по разработке программ с помощью пошаговой детализации.
1. Программа должна разрабатываться постепенно. На каждом шаге детализируется один или более операторов текущей детализации. Процесс детализации завершается, когда операторы выражены на требуемом языке программирования или когда их можно механически оттранслировать в нужный язык. 2. Детализации должны детально отражать операторы, которые они описывают. 3.