Калайда В.Т., Романенко В.В. Технология разработки программного обеспечения (1015641), страница 11
Текст из файла (страница 11)
4.13 — Размещение указателей71Только в этой процедуре известна структура данных, накоторые ссылается указатель STACK, поэтому довольно сложноизменить эту структуру за пределами процедуры.Для того чтобы определить функции обращения к стеку,можно использовать операторы ENTRY. Таким образом, всяконструкция STACK в целом имеет следующий вид:STACK: procedure;declare X POINTER;declare 1 STACK BASED(X);2 ENTRIES(100) FIXED,2 TOPOFSTACK FIXED;/* разместить стек */STACK_INITIALIZATION: ENTRY(X);.../* поместить элемент в стек */PUSH: procedure(X, элемент);...return;/* извлечь элемент из стека */POP: procedure(X, элемент);...return;...end;Рассмотренный способ удовлетворяет основным предъявляемым требованиям: имена структур и их представления разъединены, все операции со стеком сосредоточены внутри однойпроцедуры (только из этой процедуры можно обращаться к данным). Однако данному способу присущ тот же недостаток, что72и первому. С его помощью действительно строятся данные абстрактного типа, однако во многих современных языках не существует ограничений, которые гарантировали бы, что к этимданным никто не обращается, т.е.
невозможно запретитьпрограммисту напрямую обратиться к данным, на которые ссылается указатель.4.3.2.3 Защита данных от несанкционированного доступаЭтот способ организации данных подобен предыдущему,но содержит средства контроля для определения некорректныхобращений. Для определения данных этого типа добавляетсяатрибут ENVIRONMENT (среда, окружение).declare X ENVIRONMENT(STACK);Для пользователя Х — это стек, к которому можно обращаться из процедуры STACK (например, с помощью функцийPOP, PUSH, EMPTY) аналогично тому, как если бы Х было действительное число и им можно было бы оперировать, используяоперации сложения или умножения.
Пользователь не знает, каксоставлен стек, и не имеет доступа к его внутренней структуретак же, как и большинство программистов находятся в неведении относительно того, каким образом величина с плавающейточкой записывается в память ЭВМ. Стек объявляется компилятором как переменная-указатель, но при этом накладываютсядополнительные ограничения:1) обработка стека Х происходит в процедуре FUNCTIONв модуле с именем STACK;2) описание стека Х может находиться только в оператореREP (представление для переменной) в модуле STACK;3) любые другие обращения к стеку Х запрещены.С точки зрения пользователя, данные абстрактного типане должны отличаться от других переменных в программе.
Однако имеется одно существенное различие между переменнымитипа FIXED и BLIPPO. Переменная типа FIXED размещается впамяти, когда начинает выполняться процедура (или блок), содержащая объявление переменной, и освобождает память, когдапроцедура (блок) завершится. А для переменной типа BLIPPO73должна быть выделена постоянная память. Это может привестик двусмысленной ситуации.
Так как одна из целей примененияданных абстрактного типа заключается в расширении типовданных для прикладных задач, различие между типами данных,генерируемых компилятором, и данных, созданных пользователями, может вызвать недоразумения. Следовательно, одной иззадач проектирования с использованием данных абстрактноготипа должно быть автоматическое размещение таких данныхпри их использовании, так чтобы не было различий в стратегиииспользования памяти для указанных двух типов данных.Для того чтобы использовать автоматическое распределение памяти, переменная Х инициируется при вызове модуляSTACK. По существу, компилирование объявления ENVIRONMENT эквивалентно следующей записи.declare X POINTER INITIAL(STACK);При первоначальном обращении к модулю STACK распределяется память для стека Х и возвращается ее адрес в переменную-указатель. Модуль, в котором происходит обработкастека Х, имеет вид:STACK: ABSTRACTION;REP 1 STACK[X], /* имя параметра стека*/2 ENTRIES(100) FIXED,2 TOPOFSTACK FIXED;/* разместить стек *//* присвоить начальные значения */TOPOFSTACK = 0;PUSH: function(X, элемент);...end;POP:function(X, элемент);...74end;...end;Такую процедуру легко написать на современных языках,учитывая следующее.Начало процедуры ABSTRACTION предназначено дляразмещения данных абстрактного типа и присвоения им начальных значений; однако действительным распределением памятиавтоматически занимается компилятор.
Это делается для сохранения совместимости с элементарными типами данных, такими,как FIXED и REAL.Слово ABSTRACTION заменяется ключевым словомPROCEDURE и добавляется атрибут RETURN(POINTER). Кроме того, используются следующие операторы:declare DUMMY POINTER;ALLOCATE datatype SET(DUMMY);Эти операторы позволяют автоматически распределятьпамять для данных абстрактного типа. Для того чтобы обеспечить возврат из подпрограммы распределения памяти к соответствующему оператору declare, перед первым операторомFUNCTION помещают оператор RETURN(DUMMY). Вместо оператора REP объявляется структура типа BASED. Таким образом,транслятор транслирует следующие операторы:STACK: procedure RETURNS(POINTER);declare 1 STACK BASED(X),2 ENTRIES(100) FIXED,2 TOPOFSTACK FIXED;declare DUMMY POINTER;ALLOCATE STACK SET(DUMMY);TOPOFSTACK = 0;return(DUMMY);end;75Вместо оператора FUNCTION подставляется последовательность ENTRY BEGIN.
Для соответствующих операторовEND добавляются операторы RETURN. Таким образом, имеем:STACK: procedure RETURNS(POINTER);declare 1 STACK BASED(X),2 ENTRIES(100) FIXED,2 TOPOFSTACK FIXED;declare DUMMY POINTER;ALLOCATE STACK SET(DUMMY);TOPOFSTACK = 0;return(DUMMY)PUSH: function(X, элемент);...return;end;POP:function(X, элемент);...return;end;...end;Доступ к данным. При указанном способе организацииданных защитные меры приняты лишь отчасти: модуль не может получить представление любой переменной абстрактноготипа, определенное в некотором другом модуле.
Однако долженли вообще данный модуль иметь доступ к определенным данным абстрактного типа? Окончательная версия программы имеет следующую структуру:Модуль176Модуль2…МодульnПри такой структуре программы каждый модуль можетпользоваться любой функцией любого другого модуля. Однакоэто может оказаться нежелательным. Предположим, что модульX использует абстрактный тип данных Y, который, в свою очередь, обращается к абстрактному типу данных Z (рис.
4.14).XYZХ известно о Y;Y известно о Z;Х неизвестно о ZаXYZХ вызывает Z непосредственнобРис. 4.14 — Нарушение принципа информационной локализованностиПри написании программы программист, стремясь кбольшей эффективности программы, записывает вызов из модуля Х данных Z, тем самым неумышленно нарушает спецификацию относительно того, что о структуре данных Z известнотолько в модуле Y. Однако компилятор не в состоянии проверить это нарушение, а ошибка может быть выявлена гораздопозже, например, если модуль Y когда-либо изменится.В операционных системах имеется возможность защитыот некорректных действий; такую форму защиты можно добавить в языки программирования. В операционных системахимеется вектор возможностей, связанный с каждым независимо выполняемым процессом. Этот вектор описывает функции,которые может выполнять данный процесс.
Так как процессыначинаются и заканчиваются, когда задания пользователя соответственно поступают в систему или выходят из нее, вектор77возможностей динамичен, и производится проверка правомерности операций во время работы системы.В языках программирования аналогом такого вектора является право доступа. По сравнению с вектором возможностейправа доступа обладают одним значительным преимуществом:проверка производится во время компиляции, а не во время выполнения программы. Программа статична, все ее процедурыизвестны до начала выполнения, все абстрактные типы данныхизвестны, и проверка правильности обращения к данным можетбыть выполнена компилятором.Заметим, что цель использования прав доступа заключается в ограничении доступа к абстрактным типам данных, а нев обеспечении безопасности системы. Предполагается, что программист может обращаться ко всем элементам системы, поэтому права доступа могут изменяться.Контрольные вопросы1.
Язык проектирования программ PDL. Операторы выбора. Операторы цикла. Операторы описания данных.Операторы ввода/вывода и вызова процедур. Операторleave. Предложения на естественном языке.2. Нисходящее проектирование и нисходящая разработка.3. Пошаговое совершенствование.4. Восходящее проектирование.5. Подыгрывающие программы (заглушки).6. Структурное проектирование. Простая программа.Элементарная программа. Управляющие структуры,способы их описания.7. Скалярные и агрегативные типы данных.8.