nextupprevious

Next:6.1.3 Изменение действия - входные параметры
Up:6.1 Подпрограммы: процедуры и функции
Previous:6.1.1 Описание и вызов процедуры
 


6.1.2 Блоки и локализация имен

Каждая простая программа на языке Zonnon  состоит из заголовка программы (заголовка модуля) и ее тела. Тело программы -- это блок с точкой в конце. Блок задается синтаксической диаграммой рис. 6.1.
 

Block = Declarations BlockStatement SimpleName.
Declarations = { SimpleDeclaration } { ProcedureDeclaration }.
SimpleDeclaration = ( const { ConstantDeclaration ";" }| type { TypeDeclaration ";" }| var { VariableDeclaration ";" }
ProcedureDeclaration = ProcedureHeading  ";" Block ";".
ProcedureHeading = procedure ProcedureName [ FormalParameters ].
FormalParameters = "(" [ FPSection { ";" FPSection } ] ")" [ ":" FormalType ].

Рис. 6.1. Синтаксис блока

В теле программы используются объекты (константы, типы, переменные, процедуры и функции) двух сортов: локальные (их имена определены в соответствующих разделах блока) и нелокальные объекты. Нелокальные объекты программы -- это так называемые стандартные объекты, определенные в самом языке Zonnon и образующие контекст, в который "погружается" каждая Zonnon-программа. Для локальных объектов программы существенно то, что их имена связаны блоком: идентификаторы объектов имеют смысл только внутри блока, причем выбор того или другого конкретного идентификатора в качестве имени объекта не влияет на смысл этого объекта. Можно сказать, что определения локальных объектов "не видны" извне блока, в котором они находятся. Блок ограничивает и область существования локального объекта: в частности, после окончания процесса выполнения, описанного программой, пространство в памяти ЭВМ, отведенное транслятором в момент начала исполнения блока под его локальные переменные, становится снова свободным, и транслятор может его использовать произвольным образом.

Из синтаксической диаграммы видно, что каждое описание подпрограммы завершается точкой с запятой и состоит из заголовка и блока, называемого телом подпрограммы. Подпрограмма -- это не просто способ сокращения текста, но и, что более важно, средство абстракции, разложения программы на логически связанные замкнутые компоненты, определяющие ее структуру. Подпрограмма может иметь свои собственные локальные объекты, имена которых вне ее тела недоступны и которые существуют только во время исполнения подпрограммы. Например, программу СуммаДвухЧисел можно (и нужно с точки зрения любого разумного критерия качества) переписать следующим образом:

module СуммаДвухЧисел;
    var Число1, Число2, Сумма : real;
procedure Линия;
    const N = 100;
    var I : integer;
begin
    for I := 1 to N do write('-') end;
    writeln
end Линия;
begin
    read (Число1, Число2); Сумма := Число1 + Число2; Линия; Линия;
    writeLn(Число1); writeln(Число2); Линия; writeln(Сумма): Линия; Линия
end СуммаДвухЧисел.

Поскольку подпрограмма описывается как локальная по отношению к программе или другой подпрограмме, блоки в программе могут быть вложены один в другой. Блоки программы образуют иерархию по вложенности: любые два блока либо не пересекаются, либо один из них целиком содержится в другом. Поэтому для любого блока $B_1$ существует единственная последовательность объемлющих его блоков, $B_1,$$B_2,$$\ldots,$$B_n,$ в которой $B_n$ -- блок всей программы, а каждый блок $B_i$ является телом подпрограммы, описанной в блоке $B_{i+1}.$

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

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

Next:6.1.3 Изменение действия - входные параметры
Up:6.1 Подпрограммы: процедуры и функции
Previous:6.1.1 Описание и вызов процедуры


© В.Н. Касьянов, Е.В.Касьянова, 2004