Параметры-процедуры и параметры-функции
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

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

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

Для параметров-процедур и параметров-функций существуют те же правила, что и для других переменных процедурного типа: подпрограммы должны компилироваться с ключом {$F+) или иметь директиву far, не должны быть стандартными подпрограммами, не должны объявляться внутри других подпрограмм, не иметь директив inline или interrupt.

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

program EXAMPLE15;

type

Func = function(X, Y: Integer): Integer;

($F+)

function Add(X, Y: Integer): Integer;

begin

Add := X + Y

end;

function Multiply(X, Y: Integer):
Integer;

begin

Multiply := X * Y

end;

{$F-}

procedure PrintTable(A, B: Integer;Operation: Func);

{процедура печати таблицы}

var

i, j: Integer;

begin

for i := 1 to A do

begin

for j := 1 to В do

Write(Operation(i, j): 5);

WriteLn

end;

WriteLn

end;

begin {начало основной программы}

PrintTable(10, 10, Add);

PrintTable(10, 10, Multiply)

end.


ОБЛАСТЬ ДЕЙСТВИЯ ПАРАМЕТРОВ

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

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

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

Можно схематически изобразить структуру блоков некоторой программы, как показано на рис.1.

Для доступа к объектам, описанным в различных блоках, требуется соблюдать следующие правила:

1. Имена объектов, описанных в некотором блоке, считаются известными в пределах данного блока, включая и все вложенные блоки.

2. Имена объектов описанных в блоке, должны быть уникальны в пределах данного блока и могут совпадать с именами объектов из других блоков.

3. Если в некотором блоке описан объект, имя которого совпадает с именем объекта, описанного в объемлющем блоке, то это последнее имя становится недоступным в данном блоке (оно как бы экранируется одноименным объектом данного блока).

Если применить эти правила к предыдущей схеме то можно сказать, что объекты, описанные в блоке В, известны кроме самого блока В еще и в блоках С и D, но невидимы в блоке А. Объекты, описанные в блоке F, известны в пределах только этого блока.

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

В качестве примера с вложенными подпрограммами рассмотрим пример программы, определяющей количество сверхпростых чисел в натуральном ряду чисел, не превышающих 1000. Сверхпростым называется число, если оно простое и число, полученное из исходного числа, при записи цифр исходного числа в обратном порядке (перевертыш) тоже будет простым. Например, 13 и 31 —сверхпростые числа.

Program Prim7_3;

var X, К : integer; {Описание глобальных переменных X, К}

{Функция проверки числа Х на простое число}

function Prost(Y : integer):boolean;

var

D, I : integer;

Flag : boolean;

begin

D:=0; Flag:=False;

for I:=2 to Y-l do if Y mod 1=0 then D:=D+1;

if D=0 then Flag:=True;

Prost:=Flag;

end;

{Перевертыш простого числа}

function Povorot(Y:integer):integer ;

var

S:integer; {Описание локальной переменной 3}

begin

if Y<10 then S:=Y;

if (Y>10) and (Y<100) then S:=Y mod 10*10+Y div 10;

if (Y>=100) and (Y<1000)

then
S:=Y mod 10*100+Y mod 100 div 10*10+Y div 100;

Povorot:=S;

end;

begin {Начало главной программы}

Writeln(‘ ’:20,’Сверхпростые числа’);

К:=2; {2 и 3 — простые числа}

for X:=4 to 999 do

begin

if Prost(X) then {Вызов функции определения простого чис­ла х}

if Prost(Povorot(X)) then

{Вызов функции определения простого числа для числа-перевертыша полученного вычислением функции Povorot(х) от простого числа}

begin

Writeln(X); {Печать сверхпростого числа}

К:=К+1;

end;

end;

Writein(‘Всего найдено‘,К,’сверхпростых чисел < 1000 ‘);

end.


РЕКУРСИЯ

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

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

Program Prim7_4;

var N:integer;

F:longint;

function Fact(N:integer):longint;

begin

if N=1 then Fact:=1 else Fact:=N*Fact(N-1);

end;

begin {Начало главной программы}

Write('Введите число N ');

Readln(N);

F:=Fact(N);

Writeln('Для числа ',N,' значение факториала = ',F);

Readln

end.

После считывания числа N, в выражении N:=Fact(N); вызывается функция Fact с параметром-значением N. В подпрограмме функции Fact вычисления факториала проверяется условие N=1. Если оно выполняется, то функции Fact присваивается значение 1, на этом выполнение функции завершается. Если условие N=1 не соблюдается, то выполняется вычисление произведения N*Fact(N-1).Вычисление
произведения носит рекурсивный характер, так как при этом осуществляется вызов функции Fact(N-1), значение которой вычисляется, в свою очередь, через вызов функции Fact и так до тех пор, пока значение параметра N=1.

Таким образом, при выполнении рекурсивной подпрограммы осуществляется многократный переход от некоторого текущего уровня организации алгоритма к нижнему уровню последовательно до тех пор, пока, наконец, не будет получено тривиальное решение поставленной задачи. В нашем примере решение при N=1 тривиально, т.к. Fact=1. Затем осуществляется возврат на верхний уровень с последовательным вычислением функции Fact.

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


Дата: 2019-05-28, просмотров: 168.