Cтраница 2
На первый взгляд может показаться, что последовательность вызовов, приведенная на рис. 9.4 - это какое-то трюкачество. Ведь мы хотим организовать циклическое выполнение вызовов GNb, так чтобы каждый раз производилась выборка набора сегментов СИМПТОМ, НАЗНАЧЕНИЕ и ВРАЧ до тех пор, пока не будут просмотрены все сегменты, подчиненные сегменту ПАЦИЕНТ. Если DL / 1 поддерживает одну позицию в базе данных, то при первой реализации цикла последовательность вызовов прекрасно сработает. Мы произведем выборку сегментов 4 7 и 10 - именно тех, которые нужно выбрать. Однако на втором шаге будет получен код состояния GE, показывающий, что сегментов СИМПТОМ, подчиненных данному исходному, больше не существует. Перед вторичной выдачей серии вызовов текущая позиция устанавливается на сегменте 10 - первом экземпляре сегмента ВРАЧ. Чтобы дать следующий сегмент СИМПТОМ, DL / 1 должна запомнить позицию последнего выбранного сегмента СИМПТОМ, а также позиции последних сегментов НАЗНАЧЕНИЕ и ВРАЧ. [16]
В строках 18 - 30 пользователю предлагается установить последовательность вызова функций. Каждый член массива связывается с соответствующей функцией. Последовательный вызов функции осуществляется в строках 32 - 38, причем после каждого вызова на экран сразу выводится результат. [17]
![]() |
Процесс выполнения программы. [18] |
Мы уже говорили, что программа - это формальное описание последовательности вызовов предписаний, и объясняли, что проис - ( ходит при выполнении программы. [19]
![]() |
Последовательность вызовов алгоритма Фибоначчи ( 6. [20] |
Применяя этот алгоритм к подсчету шестого числа Фибоначчи, мы получим последовательность вызовов, изображенную на рис. 9.6. Исследуя это дерево, мы заключаем, что вызов Fibonacci ( 4) будет происходить дважды, а вызов Fibonacci ( 3) - три раза. [21]
![]() |
Программа расчета коэффициента для приведения базовой линии. [22] |
Далее строится сама макрокоманда в виде набора ранее составленных макрокоманд или последовательности вызовов команд на уровне строки с помощью символа S. [23]
При обращении к свойству объекта Appiicatsosi через переменную типа Variant выполняется последовательность вызовов внутренних функций механизма автоматизации: сначала вызывается метод GetlDsOftfasies [ т рф л IDispatch для получения идентификатора фулкшп. Invoke интерфейса IDispatch выполняет вызов функции. [24]
Изобразите содержимое центрального стека, как на рис. 6.5, при такой последовательности вызовов, предполагая, что используется метод моделирования с центральным стеком. [25]
Строго говоря, программа осторожный шаг описывает не одну, а две последовательности вызовов предписаний. Конкретная последовательность определяется лишь при выполнении этой программы. Таким образом, фразу программа - формальное описание последовательности вызовов предписаний, следует понимать именно в таком динамическом смысле. В рамках метафоры Универсального Выполнителя мы можем понимать программу как программу его действий - формальный текст, полностью описывающий поведение Универсального Выполнителя с учетом всех тех условий, которые могут сложиться при выполнении программы. [26]
Ключевые моменты синтаксиса Лиспа уже упоминались в предыдущих разделах: главная программа имеет форму последовательности вызовов функций, определения функций имеют форму списковых структур, в которых применяется полноскобочная кэмбриджская польская запись. Синтаксис одинаков для программ и данных. Даже примитивные операции именуются теми же атомами, которые используются в качестве данных. [27]
Главная программа на Лиспе имеет сравнительно тривиаль-ную форму: последовательность определений подпрограмм-функций, за которой следует последовательность вызовов этих функций с конкретными аргументами. Каждая подпрограмма-функция определяется отдельно. [28]
И наконец, отметим важное отличие логического программирования от традиционного, в котором нельзя произвольным образом изменять последовательность вызовов процедур, поскольку каждая процедура логически зависит, как правило, от предположения, что некоторым передаваемым ей параметрам уже будут присвоены какие-то данные в результате предшествующих событий. К логическим же процедурам, таким как Р1, может обращаться вызов сложить ( 0 1 1), фактические параметры которого не содержат переменных, или вызов сложить ( х у, 1), где переменным хну еще не присвоено никаких значений. Это свойство логических процедур, отсутствующее почти во всех других языках программирования, называется недетерминированностью входа-выхода или инвертируемостью. Суть его в том, что сама по себе процедура не определяет полностью, какие из ее формальных параметров получают входные данные из вызова, а какие возвращают ему выходные данные: напротив, их статус по отношению к входу и выходу частично определяется в соответствии с вызовом, который обращается к этой процедуре. [29]
Существует еще один подход, при котором программу, написанную на интерпретируемом языке, можно рассматривать как последовательность вызовов подпрограмм. Такую программу можно фактически расширить в длинную цепочку обращений к подпрограммам, и, наоборот, такую цепочку можно обычно упаковать в кодированной форме, которая пригодна для интерпретации. К преимуществам методов интерпретации относятся компактность представления, машинная независимость и лучшие диагностические возможности. Интерпретатор можно обычно написать так, что время, затрачиваемое собственно на интерпретацию кода и на переход к соответствующей подпрограмме, незначительно. [30]