Н. Вирт - Программирование на языке Модула-2 (1160777), страница 24
Текст из файла (страница 24)
Ее роль еще больше вслучае перемещений окна и изменения его размеров. В этом случае в модуле вызываетсяпроцедура-параметр, полученная ранее при вызове AssignRestoreProc. Такая техника работыпозволяет модулю не обращать внимание на реальное содержимое его окон: ответственность за ихвосстановление ложится на пользователя. В модуле просто определяется момент, когда нужновосстановить окно.Как уже показано в простом модуле Mouse, наличие дисплея с высоким разрешениемэкрана делает очень привлекательным метод ввода данных с помощью' указательного устройства,позиция которого задается курсором.
Наличие курсора требует значительной интеграции модуляработы с окнами с модулем управления мышью. Модуль CursorMouse, реализующий эту связь, тожеприведен в приложении.И наконец, завершается пакет модулем Menu, который тоже тесно связан со вводом мышьюи предлагает метод иерархического меню.В заключение мы попытаемся сформулировать несколько полезных правил, которыхнужно придерживаться при разработке программ, ведущих диалог с пользователем. Диалогосуществляется с использованием для ввода клавиатуры и указательного устройства (мыши), а длявывода применяется экран либо в оконном режиме, либо нет.1.
Всякому вводу текста должен предшествовать вывод строки, указывающей смыслответа.1232. Следует учитывать исправления, вносимые с помощью клавиши забоя DEL, а такжетребование завершения ввода, задаваемое с помощью определенных клавиш, таких, как RETURN(возврат каретки) или пробел.3. Определенная клавиша (обычно ESC - выход) должна быть зарезервирована длязавершения программы.4. Если используется указательное устройство, клавиатура резервируется для ввода текста(который обычно служит параметром команды), а сами команды вводятся, как правило, сиспользованием меню.5. Меню должны быть короткими, не превышать 8 команд. Помните, что выдаваемое менюможет зависеть от текущей позиции курсора, т.е.
непосредственно относиться к указываемомуобъекту или окружению.Часть 529. СРЕДСТВА ПРОГРАММИРОВАНИЯ НИЗКОГО УРОВНЯЯзыки высокого уровня поощряют и даже принуждают программиста разрабатыватьпрограммы структурированными. Структурные операторы обеспечивают высокую степеньчеткости и ясности текста программируемого алгоритма. Структурированные описания допускаютвысокий уровень абстракции при организации данных в программе и установлении соответствияданных с понятиями конкретной проблемной области.
Главное преимущество таких языков дополнительные средства контроля ошибок, поскольку структурность обеспечивает избыточность,которая может (и должна) использоваться реализаторами (в особенности компиляторов) дляопределения несоответствий в программе, которые проявляются как нарушение правил языка. Всвязи с этим понятие типов данных оказывается особенно мощным средством, а значит, и важнойособенностью языков высокого уровня.Мы, однако, осознаем, что существуют приложения, в которых правила языка в том виде,как это изложено в предыдущих разделах, оказываются слишком обременительными. Обычно этоте приложения, где данные некоторой определенной структуры должны рассматриваться какимеющие другую структуру, т.е.
там, где представление данных не определено заранее с помощьюописания, заданного языком высокого уровня. Сюда включаются также те случаи, когда структураданных должна удовлетворять условиям, накладываемым спецификой конкретной ЭВМ, короче,когда должны учитываться машинные зависимости. Структура данных, выдаваемых программой,написанной на другом языке, либо программой на Модуле, но работающей на ЭВМ другого типа,обычно описывается в терминах машинно-зависимых объектов.Еще один случай возникает, когда программы должны быть написаны для машин, вкоторых некоторые адреса памяти зарезервированы для особых целей.
Если необходим доступ кячейкам с этими адресами, то мы должны иметь возможность указать их расположение в памяти.Модула-2 как универсальный язык программирования предназначен также и для решениязадач вышеупомянутого типа и, следовательно, должен обеспечивать соответствующие средства.Они называются средствами программирования низкого уровня. поскольку позволяют проводитьрассмотрение на низком уровне абстракции, близком к используемой машине. Следовательно, ихдальнейшее рассмотрение по самой их природе должно быть неполным. Мы можем просто задатьих общую форму, а детали должны содержаться в документации, описывающей конкретнуюреализацию.Главная особенность средств низкого уровня в том, что в них отсутствует избыточность, аследовательно, не происходит проверок соответствия правилам языка.
Таким образом,программист, использующий такие средства, гораздо меньше защищен от ошибок. Поэтомунастоятельно рекомендуется применять эти средства только там, где это "действительнонеизбежно,- поскольку многие проблемы могут быть решены и привычными средствами языка.124Основным из этих средств является способ обхода контроля типов Модулы: идентификатор типаможет быть использован в качестве идентификатора Функции и обозначатьоперациюприведения. Считается, что такая функция преобразует значение типа, задаваемого параметром, всоответствующее значение того типа, который задан идентификатором Функции. Например,значение выражения с , типа CARDINAL отображается в соответствующее значение типаINTEGER функцией INTEGER(c). Функция BITSET(c) обеспечивает соответствующее значениетипа BITSET.
Эти соответствия на определяются языком Модула: информация зависит отмашины и является поэтому дополнительной. Ключевая идея таких преобразований типа состоит втом, что они не содержат никаких реальных вычислений. Если нужно битовое представлениезначения с проинтерпретировать как целое, то используется INTEGER(c), a если его нужноинтерпретировать как множество битов в слове, то BITSET(c). Программист, следовательно,должен знать особенности внутреннего представления рассматриваемого типа данных намашине. Описываемые Функции предназначены для указания желаемого способа интерпретациизначения и для отключения контроля типов.Среди средств программирования низкого уровня имеются также еще два типа данных,которые следует обсудить детальнее.
Эти типы называются WORD (слово) и ADDRESS (адрес).Память любой ЭВМ - это последовательность так называемых слов, причем каждое слово являетсяотдельно адресуемой единицей, состоящей из Фиксированного числа битов. Данные,описываемые в Модуле, отображаются компилятором в одно или несколько слов. Модула неразрешает применять к типу WORD никаких операций (кроме присваивания), поскольку такоезначение считается неинтерпретируемым.
Однако использование упоминаемых выше Функцийпреобразования типов дает возможность применять операции и к словам, так как эти функцииуказывают желаемую интерпретацию. Очевидно, что такое использование типа WORD приводит кбольшой зависимости программы от реализации, поскольку на некоторых машинах слово можетсостоять всего лишь из 8 битов. Использование этого типа автоматически делает программунемобильной.Если Формальный параметр процедуры имеет тип WORD, то соответствующий емуФактический параметр может иметь любой тип, занимающий одно слово памяти. В таком случае ввызове не требуется указывать явно преобразование типа. Например, процедуры ReadWord иWriteWord модулей Streams и FileSystem, введенных ранее, определяют параметр типа WORD.Они позволяют читать и писать последовательность слов и интерпретировать слова в соответствиис типом подставляемых параметров. В разных вызовах параметры могут иметь разный тип.
Имеяэто средство, можно читать Файлы, содержащие данные, Форматированные по правилам, невыражаемым в терминах структур данных Модулы. В качестве простого примера рассмотримзадачу чтения Файла, первое слово которого содержит его длину, а за этим словом следуют парыслов, первый элемент которых - это число, а второй имеет тип BITSET. Считая, что как типCARDINAL, так и тип BITSET занимают одно слово, эту задачу можно записать так:ReadWord(In,длина);длина := длина - 1;WHILE длина > 1 DOReadWord(in,число); ReadWord(in,множество);обработать(число,множество); длина := длина - 2ENDПравило совместимости Формального параметра типа WORD с любым типомФактического параметра (если тот занимает в памяти одно слово) обобщается в случае гибкогомассива типа WORD. А именно если формальный параметр задан как ARRAY OF WORD, толюбая переменная, структурированная или неструктурированная, может быть подставлена вкачестве Фактического параметра. Использование этого средства требует точного знанияреализуемого компилятором способа отображения структуры данных в последовательность слов.Размер, т.е.
число слов, занимаемых переменной v, определяется Функцией SIZE(v), а размер125любой переменной типа Т - Функцией TSIZE(T). SIZE является стандартной функцией Модулы, aTSIZE должна импортироваться из стандартного модуля SYSTEM.Тип ADDRESS обозначает величины, используемые в качестве адресов слов, и онопределен какTYPE ADDRESS = POINTER TO WORDСлово, на которое ссылается адрес а можно теперь обозначить а"4, где ^ - та же операцияразыменования, используемая для обычных указателей.
Значения типа ADDRESS считаютсясовместимыми по присваиванию с указателями любого типа. Это правило особенно важно вслучае параметров: если формальный параметр имеет тип ADDRESS, то соответствующий емуФактический параметр может иметь любой указательный тип. Вследствие этого, как и в случаетипа WORD, не происходит проверок соответствия типов. К операндам типа ADDRESS, крометого, могут применяться арифметические операции. В зависимости от конкретной реализацииМодулы, тип ADDRESS совместим с некоторым арифметическим типом, например CARDINAL,INTEGER, LONGINT или LONGCARD. Это средство, помимо всего прочего, позволяетзаписывать программы управления памятью.