Описание подпрограммы-функции

Begin

Описание подпрограммы-процедуры

Описание процедуры имеет вид:

Procedure имя (формальные параметры);

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

раздел операторов

End;

и помещается в разделе описаний основной программы (глобальном блоке).

Здесь имя - имя процедуры. Раздел описаний, как и в основной программе, включает разделы Label, Const, Type, Var и раздел процедур и функций. Формальные параметры представляют собой список переменных с указанием их типа. Эти переменные не описываются в разделе описаний процедуры. Допускается использование процедур без формальных параметров.

Формальные параметры могут быть трех видов:

1) параметры-значения (входные параметры);

2) параметры-переменные (выходные параметры);

3) параметры процедурного типа.

Описание входных параметров имеет вид:

список переменных 1: тип 1; список переменных 2: тип 2;…

Описание выходных параметров соответственно:

Var список переменных 1: тип 1; Var список переменных 2: тип 2; ...

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

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

Сразу за заголовком подпрограммы может следовать одна из стандартных директив ASSEMBLER, EXTERNAL, FAR, FORWARD, INLINE, INTERRUPT, NEAR. Эти директивы уточняют действия компилятора и распространяются на всю подпрограмму и только на нее, т.е. если за подпрограммой следует другая подпрограмма, стандартная директива, указанная за заголовком первой, не распространяется на вторую.

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

EXTERNAL - с помощью этой директивы объявляется внешняя подпрограмма.

FAR - компилятор должен создавать код подпрограммы, рассчитанный на дальнюю модель вызова. Директива NEAR заставит компилятор создать код, рассчитанный на ближнюю модель памяти. По умолчанию все подпрограммы, объявленные в интерфейсной части модулей, генерируются с расчетом на дальнюю модель вызова, а все остальные подпрограммы - на ближнюю модель.

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

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

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

INTERRUPT - используется при создании процедур обработки прерываний.

 

Пример 1: Составить программу для вычисления суммы квадратов натуральных чисел от 1 до n и оформить ее в виде процедуры.

Procedure Lux (N:Integer; Var Sum:Integer);

Var i:Integer;

Begin

Sum:=0;

For i:=1 To N Do Sum:=Sum + Sqr(i);

End;

Вызов процедуры в основной программе имеет вид

Lux (10,s);

Здесь s - переменная типа Integer.

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

 

Пример 2: Перемножить две квадратные матрицы A и B. Результат занести в матрицу C. В основной программе описывается тип

Type Mat = Array [1..5, 1..5] Of Real;

и заголовок процедуры тогда может иметь вид

Procedure Umn (A,B:Mat; Var C:Mat);

Подпрограмма-функция аналогична процедуре, но имеет следующие отличия.

1. Заголовок функции имеет вид

Function имя (формальные параметры): тип функции;

2. Функция имеет только один результат выполнения.

3. Результат обозначается именем функции, поэтому в разделе операторов функции обязательно должен присутствовать оператор присваивания, в левой части которого стоит имя этой функции.

4. Вызов функции в основной программе осуществляется непосредственно внутри выражения по ее имени с указанием фактических параметров.

 

Пример 3: Оформить вычисления суммы квадратов натуральных чисел от 1 до n в виде функции:

Function Lux (N:Integer): Integer;

Var s,i: Integer;

Begin

S:=0;

For i:=1 To N Do S:=S + Sqr(i);

Lux:=S;

End;

 

Вызов функции в основной программе может иметь вид

W:=Lux (10);

Здесь W – переменная типа Integer.

Замечание. При использовании подпрограмм процедур и функций следует иметь в виду, что переменные, представленные в разделе описания основной программы (Program), действуют в разделе операторов основной программы и в любой ее подпрограмме. Эти переменные называются глобальными. Переменные, описанные в подпрограмме, действуют только в этой подпрограмме и в любой объявленной в ней процедуре и функции. Такие переменные называются локальными. Они недоступны для операторов основной программы и других подпрограмм.

Пример 4:В программе вводится пара чисел X и Y и выводится на экран дисплея результат возведения X сначала в степень +Y, а затем - в степень -Y. Для выхода из программы нужно ввести Ctrl-Z и Enter.

var х,у:Real;

Function Power (a, b : Real): Real;

begin {Power}

if a > 0 then Power := exp(b * Ln (a))

else

if a < 0 then Power := exp(b * Ln(abs(a))

else

if b = 0 then Power := 1

else Power := 0

end {Power} ;

{--------------------}

begin {main}

repeat

readln(x,y) ;

writeln (Power (x,y) :12:10, Power (x, -y) : 15 : 10)

until EOF

end {main} .

 

Пример 5:В программе задаются два целых числа 5 и 7, эти числа передаются процедуре INC2, в которой они удваиваются. Один из параметров передается как параметр-переменная, другой - как параметр-значение. Значения параметров до и после вызова процедуры, а также результат их удвоения выводятся на экран.

а : Integer = 5;

b : Integer = 7 ;

{-----------------}

Procedure Inc2 (var c: Integer; b: Integer) ;

begin {Inc2}

с := с + с;

b := b + b;

WriteLn ( 'удвоенные: ', c:5, b:5)

end {inc2};

{--------------}

begin {main}

WriteLn('исходные: ', a:5, b:5);

Inc2(a,b);

WriteLn('результат: ', a:5, b:5)

end {main}.

В результате прогона программы будет выведено:

исходные: 5 7

удвоенные: 10 14

результат: 10 7

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

Контрольные вопросы

1. Дайте определение понятию «подпрограмма».

2. Структура подпрограммы. Опишите входящие в нее компоненты.

3. Опишите порядок обращения подпрограмм друг к другу.

4. Дайте определение понятию «подпрограмма-процедура».

5. Дайте определение формальным параметрам. Опишите их виды.

6. Перечислите стандартные директивы и назовите действия, которые они задают компилятору.

7. Опишите вызов процедуры. Примеры.

8. Дайте определение понятию «подпрограмма-функция».

9. Назовите различия между глобальными и локальными переменными.