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

Примечание. Приведенные выше правила допускают передачу управления на оператор из некоторой объемлющей последовательности операторов, но не наоборот. Аналогично, они запрещают передачу управления между альтернативами оператора выбора, условного оператора или оператора отбора, между обработчиками исключе­ний или из обработчика исключения некоторого окружения назад на последователь­ность операторов этого окружения.

Пример:

« СРАВНИТЬ»

if А (I) < ЭЛЕМЕНТ then

if ЛЕВЫЙ (I)/= 0 then

  1. = ЛЕВЫЙ (Г);

goto СРАВНИТЬ;

end if;

- - некоторые операторы

end if;

6. ПОДПРОГРАММЫ

Подпрограммы являются одной из четырех форм программных моду­лей, из которых могут быть составлены программы. Другие формы — это пакеты, заданные модули и настраиваемые модули.

Подпрограмма - это программный модуль, выполнение которого ини­циируется вызовом подпрограммы. Существуют две формы подпрограмм: процедуры и функции. Вызов процедуры — это оператор; вызов функции является выражением и возвращает значение. Определение подпрограммы может состоять из двух частей: описания подпрограммы, определяющего соглашения о ее вызове, и тела подпрограммы, определяющего ее выпол­нение.

  1. Описание подпрограммы

Описание подпрограммы объявляет процедуру или функцию в зависи­мости от указанного начального зарезервированного слова.

описание_подпрограммы : : = спецификация—подпрограммы;

спецификация—подпрограммы : : =

procedure идентификатор [раздел—формальных—параметров]

I function обозначение [раздел_формальных_параметров] return обозначение_типа

обозначение : : = идентификатор | знак-операции

знак_операции : : = строковый_литерал

раздел—формальных—параметров : : =

(спецификация—параметра {; спецификация—параметра}) спецификация—параметра : : =

список—идентификаторов : вид обозначение—типа [: = выражение] вид : : = [in] | in out | out

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

Спецификация параметра с несколькими идентификаторами эквива­лентна последовательности спецификаций с одним параметром, как поясняет­ся в разд 3.2. Каждая спецификация одного параметра описывает формаль­ный параметр. Если вид явно не задан, то предполагается вид in. Если спе­цификация параметра оканчивается выражением, то оно является выраже­нием по умолчанию формального параметра. Выражение по умолчанию до­пустимо только в спецификации параметра вида in (независимо от явного или неявного его указания). Тип выражения по умолчанию должен совпа­дать с типом соответствующего формального параметра.



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

Предвыполнение описания подпрограммы предвыполняет соответству­ющий раздел формальных параметров. Предвыполнение раздела формаль­ных параметров не дает другого эффекта.

Примеры описания подпрограмм:

procedure ОБХОД_ДЕРЕВА;

procedure УВЕЛИЧЕНИЕ (X: in out INTEGER);

procedure ПРАВЫЙ_АБЗАЦ (ПРЕДЕЛЫ: out РАЗМЕР_СТРОЧКИ); - - см. 3.5.4

procedure ПЕРЕКЛЮЧАТЕЛЬ (ИЗ, В: in out СВЯЗЬ); - - см. 3.8.1

function СЛУЧАЙНАЯ_ВЕЛИЧИНА return ВЕРОЯТНОСТЬ; - -см. 3.5.7

function МИН_ЯЧЕЙКА (X: СВЯЗЬ) return ЯЧЕЙКА; --3.8.1

function СЛЕДУЮЩЕЕ_ОБРАМЛЕНИЕ (К: POSITIVE) return ОБРАМЛЕНИЕ;

- - см. 3.8

function СКАЛ-ПРОИЗВЕДЕНИЕ (ЛЕВЫЙ, ПРАВЫЙ: ВЕКТОР) return ВЕЩЕСТВ;

- - см. 3.6

function (ЛЕВЫЙ, ПРАВЫЙ: МАТРИЦА) return МАТРИЦА; - - см. 3.6

Примеры параметров с выражениями по умолчанию:

procedure ПЕЧАТЬ-ЗАГОЛОВКА (СТРАНИЦЫ: in NATURAL;

ЗАГОЛОВОК: in СТРОЧКА: = (1. .СТРОЧКА' LAST =>" );

ЦЕНТР: in BOOLEAN: = TRUE); - - см. 3.6

Примечание. Вычисление выражений по умолчанию начинается при определенных вызовах подпрограмм, как пояснено в ргізд. 6.4.2 (выражения по умолчанию не вычис­ляются при предвыполнении описания подпрограммы).

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

  1. Виды формальных параметров

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

Виды формальных параметров подпрограммы приведены в табл. 6.1.

Таблица 6.1

П

Вид

in

in out
out

ояснение

Формальный параметр - константа, разрешается только чтение зна­чения соответствующего фактического параметра

Формальный параметр - переменная, разрешается как чтение, так и изменение значения соответствующего фактического параметра

Формальный параметр - переменная, разрешается изменение значе­ния соответствующего фактического параметра. Значение скалярного параметра, которое не изменяется при вызове, после возврата не опре­делено; то же самое имеет место для значения скалярного подкомпо­нента, отличного от дискриминанта. Допускается чтение границ и дис­криминантов формального параметра и его подкомпонентов; никакое другое чтение не допускаетсяДля скалярного параметра такой эффект достигается копированием: в начале каждого вызова значение фактического параметра, соответствующе­го формальному параметру вида in или in out, копируется в этом формаль­ном параметре (прямое копирование); затем после нормального оконча­ния тела подпрограммы значение формального параметра вида in out или out копируется обратно в соответствующем фактическом параметре (об­ратное копирование). Для параметра ссылочного типа прямое копирование используется для всех трех видов, а обратное - для видов in out и out.

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

Для параметра личного типа вышеуказанный эффект достигается по правилу, которое применяется к соответствующему полному описанию типа.

В теле подпрограммы формальный параметр отвечает любому ограниче­нию, вытекающему из обозначения типа, данного в спецификации этого па­раметра. В качестве границ формального параметра неограниченного индек­сируемого типа берутся границы фактического параметра (см. 3.6.1). Для формального параметра, описание которого задает неограниченный (лич­ный или именуемый) тип с дискриминантами, дискриминанты этого фор­мального параметра инициализируются значениями соответствующих дис­криминантов фактического параметра; формальный параметр неограничен тогда и только тогда, когда его вид in out или out, и имя переменной, явля­ющейся фактическим параметром, обозначает неограниченную переменную (см. 3.7.1 и 6.4.1).

Если фактический параметр вызова подпрограммы является подкомпо­нентом, который зависит от дискриминантов переменной неограниченного именуемого типа, то выполнение вызова ошибочно, если значение любого дискриминанта переменной изменяется при этом выполнении; это правило не применяется, если вид параметра in и тип подкомпонента — скалярный тип или ссылочный тип.

Примечание. Из правил передачи параметров индексируемого и именуемого типов следует:

  • Если выполнение подпрограммы прекращено в результате возбуждения исклю­чения, конечное значение фактического параметра такого типа может быть либо тем же, что и до вызова, либо значением, присвоенным формальному параметру во время выполнения подпрограммы.

  • Если доступ ко всем фактическим параметрам такого типа осуществляется од­ним способом, то результат вызова подпрограммы (при отсутствии исключения) не зависит от того, использует ли реализация для передачи параметров копирование. Ес­ли, однако, доступ к фактическому параметру осуществляется несколькими способа­ми (например, если глобальная переменная или другой формальный параметр ссыла­ется на один и тот же фактический параметр), то значение формального параметра пос­ле изменения фактического способом, отличным от изменения формального, неопре­деленно. Программа, использующая такое неопределенное значение, является оши­бочной.

Такие же виды параметров определены и для формальных параметров входов (см. 9.5) с тем же смыслом, что и для подпрограмм. Для формальных параметров на­стройки определены другие виды параметров (см. 12.1.1).

Для всех видов справедливо, что если фактический параметр указывает задачу, то соответствующий формальный параметр указывает ту же задачу; то же самое имеет место для подкомпонента фактического параметра и соответствующего подкомпонен­та формального параметра.

  1. Тела подпрограмм

Тело подпрограммы определяет ее выполнение

тело_подпрограммы : : =

спецификация_подпрограммы is

[раздел—описаний]

begin

последовательность_операторов

[exception

обработчик —исключения

{обработчик—исключения}]

end [обозначение] ;

Описание подпрограммы необязательно. При отсутствии описания спе­цификация подпрограммы в ее теле (или в следе тела) играет роль описа­ния. Для каждого описания подпрограммы должно быть соответствующее ему тело (кроме подпрограмм, написанных на другом языке, как поясня­ется в разд. 13.9). Если даны и описание, и тело, то спецификация подпро­граммы в теле должна быть согласована со спецификацией подпрограммы в описании (см. разд. 6.3.1 о правилах согласования).

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

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

Выполнение тела подпрограммы инициируется вызовом подпрограммы (см. 6.4). Для этого, после установления соответствия между формальны­ми и фактическими параметрами, предвыполняется раздел описаний тела и выполняется последовательность операторов тела подпрограммы. По окон­чании выполнения тела осуществляется возврат в место вызова (и необхо­димое обратное копирование значений формальных параметров в фактичес­кие (см. 6.2) ). Необязательные обработчики исключений, заданные в конце тела подпрограммы, выполняются при возбуждении исключений во время выполнения последовательности операторов тела подпрограммы (см. 11.4).

Примечание. Из правил видимости следует, что если описанная в пакете подпро­грамма обязана быть видимой вне пакета, то спецификация полпрограммы должна быть дана в видимой части пакета. Эти же правила предписывают, что описание под­программы должно быть дано, если вызов подпрограммы возникает текстуально до тела подпрограммы (описание должно помещаться в тексте программы раньше вы­зова). Данные в разд. 3.9 и 7.1 правила подразумевают, что описание подпрограммы и соответствующее ему тело должны находиться непосредственно в одной и той же зо­не описаний.

Пример тела подпрограммы:

procedure ПРОТАЛКИВАНИЕ (Е: in ТИП_ЭЛЕМЕНТА; С: in out СТЕК) is begin

if С.ИНДЕКС = C.PA3MEP then raise ПЕРЕПОЛНЕНИЕ- СЕТКА;

else

С.ИНДЕКС: = С.ИНДЕКС + 1;

C.MECTO (С.ИНДЕКС): = E;

end if;

end ПРОТАЛКИВАНИЕ;

  1. П p а в и л а согласования

Всякий раз, когда правила языка требуют или допускают появления спецификации данной подпрограммы более одного раза, в каждом месте допустимы следующие вариации:

  • Числовой литерал может быть заменен другим числовым литералом тогда и только тогда, когда они имеют одно и то же значение.

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

  • Строковый литерал в качестве знака операции может быть заменен на другой строковый литерал тогда и только тогда, когда они представля­ют одну и ту же операцию (см. 8.5).

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

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