Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

3345

.pdf
Скачиваний:
2
Добавлен:
15.11.2022
Размер:
4.34 Mб
Скачать

структура Алгола (begin - end) дает типичный пример: при входе в блок каждая декларация выполняет функцию именования, создавая новую ассоциацию между идентификатором и простой переменной, массивом, подпрограммой. Одновременно деактивируются все прежде существовавшие ассоциации для каждого идентификатора. Ссылки внутри блока пользуются этими вновь созданными активными ассоциациями для каждого идентификатора. Выход из блока вызывает разыменование ассоциаций, созданных при входе, и повторное активирование ассоциаций, которые при входе были деактивированы.

Итак, имеется 5 основных операций управления данными, причастных к ассоциациям идентификаторов.

1.Именование. Операция создания ассоциации между идентификатором и объектом программы или данных.

2.Разыменование. Операция уничтожения ассоциации между идентификатором и ассоциированным с ним объектом.

3.Активирование. Операция приведения в активное состояние существующей ассоциации между идентификатором и объектом программы или данных, делающая эту ассоциацию пригодной для использования в ссылках.

4.Деактивирование. Операция, делающая неактивной существующую ассоциацию между идентификатором и объектом программы или данных.

5.Операция обработки ссылки. Операция поиска программного объекта или объекта данных, который ассоциирован в текущий момент с данным идентификатором, с использованием единственной активной в этот момент ассоциации для данного идентификатора.

При изучении управления данными оказывается полезным понятие среда ссылок, о которой упоминалось в разделе 3.8.3. Именно среда, как множество активных ассоциаций идентификатора, определяет для каждой встретившейся ссылки соответствующую ей ассоциацию. Операции именования, разыменования, активирования и деактивирования изменяют среду ссылок.

Ссылка на идентификатор называется локальной, если она использует ассоциацию, активную только внутри выполняемых в

181

настоящий момент блока или подпрограммы. В Алголе - ссылка на идентификатор, описанный в блоке, вход в который выполнен позднее всего. Глобальной ссылкой называется ссылка на ассоциацию, активную на протяжении всего выполнения программы, то есть ссылки на идентификаторы, описанные в самом внешнем блоке. Нелокальная ссылка - любая ссылка, не являющаяся локальной, то есть ссылка, описанная в блоках промежуточного уровня между самым внешним и самым внутренним.

Удобно также ввести термин локальная среда ссылок или локальная среда для обозначения локальных ассоциаций, появившихся при последнем изменении среды ссылок. Нелокальная среда - это остальная часть среды ссылок в любой момент времени. Обычно локальная среда подпрограммы включает формальные параметры и локальные переменные, декларированные в заголовке подпрограммы. Нелокальная среда содержит ассоциации идентификаторов, общих для этой и других подпрограмм. Это все важно, ибо ЯзПр уходят в область локализации, расширяющую трактовку управления данными.

3.9.1. Простые подпрограммы без параметров

Мы начнем с простых структур управления данными и будем переходить к более сложным. Рассмотрим сначала обычную иерархию подпрограмм: главную программу и несколько подпрограмм, вызывающих друг друга обычным образом (то есть мы пока пренебрегаем параметрами и отказываемся от рекурсии). В эту категорию попадают блоки в ЯзПр с блочной структурой (например, Алгол).

В таких языках каждая программа и подпрограмма организована в виде множества вложенных блоков, ограниченных символами begin и end (в Алголе), скобками {…} (в С++), являющимися средствами группирования программных структур. Каждый блок при этом начинается с ряда деклараций, преследующих две цели:

1.Именование. Каждая декларация создает ассоциацию для одного или нескольких идентификаторов. Эти ассоциации составляют локальную среду ссылок для блока.

2.Создание структур данных. Некоторые декларации могут также указывать на необходимость создания при входе в блок

182

структур данных или простых переменных.

То есть блок представляет собой некоторый замкнутый фрагмент программы, использующий внутри себя новые объекты, и выполняющий достаточно самостоятельные вычисления.

Блочная структура при надлежащей обработке позволяет использовать чрезвычайно простую и естественную схему управления памятью, основанную на стеке (см. п.3.5.1 - стек), и обеспечивает весьма гибкую структуру управления данными. Можно считать блочную структуру структурой управления данными, действующими внутри подпрограмм и позволяющей изменять среду ссылок в произвольный момент выполнения программ, а не только при входе и выходе из блока. То есть блок представляет собой простую подпрограмму без параметров, непосредственно вставленную в точку вызова, когда инструкция вызова подпрограммы заменена на тело процедуры.

Подпрограмма имеет локальную среду, состоящую из тех ассоциаций идентификаторов, которые активируются при входе в нее. Кроме того, подпрограмма может иметь нелокальную среду ссылок, состоящую из ассоциаций, общих с другими подпрограммами. В разных локальных средах ряда подпрограмм может использоваться много одинаковых идентификаторов, но с различными ассоциациями в каждой среде. При передачах и возвратах управления между подпрограммами текущая среда ссылок должна так видоизменяться, чтобы отражать соответствующую локальную среду ссылок в каждой подпрограмме. Тут возможны два случая, создаваемые синтаксисом существующих ЯзПр: локальная среда при переходах из программ деактивируется - активируется, сохраняясь при этом; локальная среда при выходе уничтожается и создается вновь при возврате. Рассмотрим, как это реализуется.

Локальная среда во время выполнения представлена таблицей локальных ассоциаций типа "идентификатор - указатель на элемент программы или данных, с которым он ассоциирован в данный момент".

При реализации первого случая таблица локальной среды подпрограммы объединяется с командами этой подпрограммы. Такое объединение среды с выполняемыми командами обеспечивает

183

автоматическое изменение локальной среды при передачах управления от одной подпрограммы к другой. В некотором смысле изменения среды скомпилированы и включены в выполняемые команды, что обеспечивает неявное изменение среды.

В основе второго метода лежит использование центрального стека таблиц локальной среды. Первоначально в стеке содержится только таблица для главной программы. Когда главная программа вызывает подпрограмму, для нее создается таблица и помещается

ввершину стека. Если эта подпрограмма вызывает другую, то ее таблица заносится в стек сверху таблицы вызвавшей подпрограммы, то есть "прячется" вглубь отведенной памяти и выполняется в первую очередь. Когда подпрограмма заканчивается, ее таблица из стека удаляется (см. рис. 6.5, с.214).

Хотя первый метод более удобный и простой, но его нельзя использовать при реализации рекурсивных подпрограмм, которые

внастоящее время очень распространены.

3.9.2.Подпрограммы с параметрами: способы передачи

параметров

Совместное использование данных различными подпрограммами обеспечивается чаще всего передачей параметров. Параметр - это элемент информации, необходимый для того, чтобы подпрограмма могла выполнить свою задачу. Помещение соответствующей информации в процедуру называется передачей параметров.

Однако, возможно задействование процедуры и без передачи параметров путем совместного использования подпрограммами нелокальной среды. В этом случае при входе в подпрограмму наряду с обычными локальными ассоциациями активируются и нелокальные (общие) ассоциации. Использование нелокальной среды имеет место в том случае, когда при всех вызовах подпрограмм используются одни и те же данные. Если же при каждом вызове подпрограммы ей требуется передать для обработки различные данные, то используются способы передачи параметров.

При обсуждении передачи параметров следует различать фактические параметры (или аргументы) и формальные параметры.

184

Формальные параметры - это идентификаторы, используемые в определении подпрограммы в качестве имени элемента подпрограммы или элемента данных, передаваемого подпрограмме. Они обычно описываются в списке формальных параметров в начале определения подпрограммы, причем они непременно должны быть простыми идентификаторами.

Фактические параметры - это выражения, используемые в точке вызова подпрограммы для описания передаваемого ей элемента программы или данных. В соответствии с обычным синтаксисом фактические параметры записываются в виде списка вслед за именем подпрограммы, например SUB (x2*y,17).

Передача параметров служит тем механизмом, который позволяет подпрограммам обращаться к нелокальной информации через вполне локальные идентификаторы. Благодаря им можно избавиться от сложности нелокальных сред.

Формальные параметры являются локальными идентификаторами и механизм передачи параметров дает средства начального присваивания этим локальным идентификаторам нелокальных значений при входе. Для этого между формальными параметрами и фактическими параметрами, описанными в точке вызова, устанавливается простое позиционное соответствие. Для этого в точке вызова имеется список фактических параметров, а в заголовке определения подпрограммы имеется список формальных параметров. Во время входа в подпрограмму первый формальный параметр ассоциируется с элементом данных или элементом подпрограммы, обозначаемым как первый фактический параметр, второй формальный параметр ассоциируется со вторым фактическим параметром и т.д. То есть соблюдается позиционное соответствие между списками формальных и фактических параметров. Сложности возникают из-за разнообразия типов фактических параметров и способов их передачи. Рассмотрим сначала способы.

В ЯзПр используются три основных способа передачи параметров: передача по значению, по ссылке и передача по имени. Они определяют различные правила вычисления для фактических параметров.

185

Передача по значению. В этом случае фактический параметр вычисляется в точке вызова. После этого вычисленное значение фактического параметра передается подпрограмме и становится ее начальным значением, ассоциированным с соответствующим формальным параметром. Главной отличительной особенностью этого способа передачи является его односторонность, он допускает передачу данных только в подпрограмму. То есть подпрограмма не может вернуть результаты в вызывающую программу, защищая тем самым ее от побочных эффектов при присваивании значений формальным параметрам в вызываемой программе.

Передача по ссылке (по адресу или по простому имени). В этом случае передается некоторый указатель, обычно на место, где содержится значение параметра. Так как после передачи указатель оказывается в обеих подпрограммах, то любая ссылка на "принятый" указатель будет и ссылкой на передающий. Поэтому передача по ссылке позволяет передавать данные как в подпрограмму, так и из нее.

Передача по имени. В этом случае фактические параметры не вычисляются до момента использования их в вызываемой подпрограмме. Параметры должны передаваться невычисленными и момент их вычисления определяется вызываемой подпрограммой. Имеет ограниченное применение из-за затрат на моделирование определения значения.

Из типов фактических параметров рассмотрим только следующие три:

Простые переменные. (1) Передача по значению. Переменная вычисляется в точке вызова и передается подпрограмме. Это значение становится начальным значением соответствующего формального параметра, который при выполнении подпрограммы рассматривается как локальная простая переменная. (2) Передача по ссылке. Находится позиция памяти, связанная с именем переменной в среде ссылок в момент вызова и передается указатель на эту позицию. (3) Передача по имени аналогична передаче по ссылке;

Константы. (1) Передача по значению. Передаются подпрограмме и присваиваются формальному параметру как начальное значение. (2) Передача по ссылке. Для константы отводится пози-

186

ция памяти, в которую заносится ее значение. Передается указатель на эту позицию. (3) Передача по имени аналогична изложенным;

Структуры данных. (1) Передача по значению. В Алголе массив копируется в момент вызова и подпрограмме передается указатель на копию. Требует дополнительной памяти на размещение копии. Чаще передачу структуры по значению не отличают от передачи по ссылке - передают указатель на структуру. Аналогично производится и передача по имени.

3.9.3. Передача результатов из подпрограмм

Используются три основных способа передачи результатов.

Это:

1)значения функций;

2)изменяемые параметры;

3)изменения значений нелокальных переменных (побочные эффекты). Их механизмы описываются синтаксисом ЯзПр, то есть общих моментов, кроме конкретики синтаксиса ЯзПр, нет.

Подводя итог сказанному, можно сделать следующие выво-

ды:

с помощью структур данных можно объединить данные различных типов в одно составное значение, но оставив распределенным их взаимодействие с необходимыми операциями, из-за этого интересующая нас для защиты информация равномерно (серо) распределяется по компьютеру;

с помощью класса, как абстрактного типа данных, в один составной объект можно объединить данные и функции. Тем самым операционное взаимодействие данных резко кристаллизуется и локализуется. Из-за этого отчетливо формируются центры внимания за сгустками информации, подлежащей защите.

3.10.Основные свойства и содержание алгоритмов обработки структур данных

Данное в п.3.1 понятие алгоритма по А. Тьюрингу математически является глубоким, но очень негибким для практической

187

деятельности по построению алгоритмов. Их построение обычно осуществляется в 8 этапов:

1.Постановка задачи.

2.Построение модели.

3.Разработка алгоритма.

4.Проверка правильности алгоритма.

5.Реализация алгоритма.

6.Анализ алгоритма и его сложности.

7.Проверка программы.

8.Составление документации, … по ГОСТу, включающей 4 части.

При этом перечисленные этапы нельзя рассматривать изолированно, особенно 1, 2 и 3, а также 6 и 7 в совокупности с 1 – 3 этапами.

Нестрогое интуитивное представление об алгоритме дает следующее определение: алгоритм – однозначно трактуемая процедура решения задачи в виде конечной последовательности точно определенных шагов или операций, для выполнения которых требуется конечный объем оперативной памяти и конечное время. В ходе разработки и использования алгоритм проходит ряд стадий, выражаемых в следующих формах:

словесного описания; формализованной схемы; математической записи; пошаговой форме; блок-схемы; операторной;

синтаксиса ЯзПр высокого уровня; ассемблерной;

символов машинной (двоичной) арифметики и логики.

Так как мы рассматриваем алгоритмы компьютерной обработки, то нам необходимо ввести в определение алгоритма некоторые «детали» описания компьютера. Это можно сделать, описав «типичный» современный компьютер и язык общения с ним и оп-

188

ределив алгоритм как процедуру, которая может быть реализована на этом компьютере при помощи этого языка.

Этот компьютер будет иметь неограниченную память с произвольным доступом, в которой могут храниться действительные и целые числа, а также логические константы. В одном слове этой памяти можно хранить произвольное конечное число (тут «натяжка» – Ю.Б.) и можно извлечь любое слово за фиксированное, постоянное время.

Такой компьютер может выполнить хранимую программу, которая состоит из допустимой последовательности команд, охватывающей все стандартные арифметические операции, операции сравнения, перехода и т.д. Обычно мы будем считать, что каждая такая команда выполняется за единицу времени. Простыми описаниями часть памяти компьютера может быть организована в одно-, двух- и трехмерные массивы. Мы будем пользоваться языками Фортран и Алгол (упрощенные) в качестве модели возможностей нашей машины, если нужно будет что-то конкретизировать.

Тем самым мы утверждаем, что только тогда имеется алгоритм для решения задачи, когда можно написать программу для ЭВМ, решающую эту задачу. Это спорно и ограниченно, но это ограниченное определение, как раз то, что нам требуется. Чтобы поставить все на свои места, давайте решим следующий пример.

Алгоритм MAX. Даны N действительных чисел в одномерном массиве R(1), R(2), …, R(N), найти такие M и J, что

M R( J ) max R( K ),

1 K N

где М – наибольшее число в массиве; J – ближайший номер этого числа.

В случае, когда два или более элементов R имеют наибольшее значение, запоминается наименьшее значение J.

189

Шаг 0. [Установка в начальное состояние, или инициализа-

ция]

Set M R(1); and J 1. (Фортран),

где запись А В означает оператор присваивания, то есть переменной А присваивается текущее значение В.

Шаг 1. [N=1?] If N=1 then STOP fi (конец конструкции if)/

Шаг 2. [Проверка каждого числа] For K

2 to N do шаг 3 od

(конец конструкции do]; and STOP.

 

Шаг 3. [Сравнение] If M<R(K) then set M

R(K); and J K (те-

перь М =наибольшее число из проверенных, а K – его номер в массиве).

Алгоритм MAX не закодирован на каком-либо языке, а записан в форме, которую легче воспринять; он выражен в виде шагов, которые легко реализуются в каждом общепринятом ЯзПр. От такого представления нетрудно перейти к кодовой форме. Однако так бывает не всегда.

Доказательство правильности алгоритма – это один из наиболее трудных и утомительных этапов создания алгоритма. Наиболее распространенная процедура доказательства правильности программы – это прогон ее на разных тестах.

Если выданные программой ответы могут быть подтверждены известными (особенно, полученных из независимых источников) или вычисленными вручную данными, то, может быть, программа работает правильно.

Можно предложить еще одну методику проверки правильности алгоритма. Предположим, что алгоритм описан в виде последовательности шагов, скажем, от 0-го до шага m. Постараемся предположить некое обоснование правомерности каждого шага. А это значительно проще проверки (доказательства) алгоритма целиком, ибо часть всегда проще (прозрачнее) целого. Аналогичная задача возникает при анализе чувствительности (точности) алгоритма.

Под чувствительностью алгоритма (Чa) понимается степень изменения его результата при отклонении влияющих на его значение параметров. В качестве показателя чувствительности исполь-

190

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]