Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Процедуры и функции (96

..pdf
Скачиваний:
0
Добавлен:
15.11.2022
Размер:
195.17 Кб
Скачать

Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ния. Эти параметры предназначаются только для передачи данных в подпрограмму, но не для получения от нее результата.

Например:

Procedure E1 (par1: type1; par2: type2; par3, par4 : type3);

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

Procedure SetData (Year, Month, Day: word);

Все три параметра: Year, Month, Day — параметры-значения. Параметры-переменные — это формальные параметры. При описании заголовков процедур/функций перед идентификаторами параметров-переменных ставится ключевое слово var, что позволяет информации передаваться из подпрограммы в основную про-

грамму.

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

Рис. 3

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

11

Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 4

Вячейки памяти формального параметра передается адрес фактического параметра: по имеющемуся адресу разрешено только брать значения фактического параметра, а изменять его значения запрещено, т. е. обратного влияния нет (рис. 4).

Вкачестве фактического параметра-константы могут исполь-

зоваться как переменные, так и константы различных типов. Не допускаются файловые типы.

Например:

Procedure MGTU1 (var par1, par2: type1; par3, par4: type2);

где par1, par2 — параметры-переменные; par3, par4 — параметрызначения.

Procedure MGTU2 (const par1, par2: type1; var par3, par4: type2; par5, par6: type3);

здесь par1, par2 — параметры-константы; par3, par4 — параметрыпеременные; par5, par6 — параметры-значения.

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

Procedure GetData (Var Year, Month, Day: word);

Все три параметра Year, Month, Day — параметры-переменные типа Word.

Если в заголовке процедуры тип параметра не указывается, то такой параметр называется бестиповым.

Procedure NOTYPE (Var Par1, Par2; const Par3, Par4).

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

12

Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

другие данные. Но внутри подпрограммы должен быть явно описан тип, к которому направляются бестиповые переменные.

Передача параметров в процедурах и функциях через открытые массивы

Открытый массив — это массив без определения его границ, т. е. без указания его размерности. Для объявления такого массива применяется обычное объявление массива, но без указания размерности:

Type

T_OpenArray=array of char; Var

Vodmas: T_OpenArray of byte;

Procedure Test( OpenArray: T_OpenArray); Function Test1(OpenArray:array of byte) : real;

В подпрограмме нижняя граница массива определяется как нулевая через функцию Low(OpenArray), верхняя граница определяется через функцию High(OpenArray), размер массива определяется функцией SizeOf(OpenArray).

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

1. В разделе описания Type описать пользовательский тип как функцию (или процедуру) с соответствующими параметрами без указания имени функции (или процедуры), например:

Type

TfuncPar = Function (X:Real): Real; TprocPar = Procedure (Y:byte;ch:char);

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

3.Процедуры, передаваемые в качестве параметров, необходимо обязательно заключать между директивами компилятора {$F+}

и{$F-}, т. е. оттранслировать с опцией {$F+} или описать с директивой Far — дальней модели вызова.

13

Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Процедуры не должны быть:

стандартными процедурами или функциями;

вложенными процедурами или функциями;

inline-процедурами или функциями;

interrupt-процедурами или функциями.

4.Связать переменные типа функции/процедуры с пользовательской процедурой или функцией.

5.Передать в процедуру значение этой переменной или непосредственно передавать имя процедуры или функции.

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

Использование процедур и функций

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

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

При передаче параметров подпрограмм вместо формальных параметров-значений можно использовать целые выражения, но

тип выражения должен соответствовать типу формального параметра.

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

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

14

Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Область действия (сфера видимости) идентификаторов при использовании процедур и функций

Областью действия (сферой видимости) идентификатора

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

определяется местом их объявления. Если идентификаторы допускается использовать только в рамках одной процедуры или функции, то такие идентификаторы называются локальными.

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

Рассмотрим сказанное на примере (рис. 5).

Рис. 5

Рассмотренный пример показывает, что переменные A0, B0, C0, описанные в основной программе, являются глобальными переменными для всех процедур и функций, т. е. их можно использовать в самих процедурах. Переменные A1, B1, C1 являются

15

Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

глобальными для всех процедур и функций, вложенных в процедуру Parlok, но в самой процедуре они локальные. Переменные А2, В2, С2, объявленные в описательной части самой внутренней процедуры Parlok1, и формальная переменная Р1, описанная в заголовке процедуры, являются локальными. Из процедуры Parlok1 можно обращаться к переменным A2, B2, C2 как описанным в теле процедуры, а также к переменным A1, B1, C1 и A0, B0, C0 как видимым из процедуры в качестве глобальных параметров.

Из программы DEMO нельзя обратиться к переменным A1, B1, C1 и A2, B2, C2, так как они локальны и не видны программе.

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

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

1.Локальные переменные действуют локально там, где они определены и могут выступать в качестве глобальных, если они окружают контекст процедур или функций.

2.Локальные переменные процедур/функций никогда не работают во внешнем окружении.

3.В случае совпадения имен глобальной и локальной переменной действовать будет только локальная переменная. Локальная переменная перекрывает значение глобальной переменной в основной программе, если локальная переменная передается основной программе и ее имя совпадает с именем глобальной переменной.

Отсюда следует важный вывод: если подпрограмма что-то передает в вызывающую программу, то подпрограмма ничего не должна изменять в основной программе!

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

16

Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 6

Перекрытие глобальных переменных и констант

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

Program Proba; {перекрытие глобальных переменных} Const

A : integer=5; B : integer=7; Var C : integer;

Procedure Uvel (var c : integer; b: integer) {удвоение элементов}

begin

c := c+c; b := b+b;

17

Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

writeln (‘Удвоение C и B процедурой в процессе решения :’ , c:5,

b:5)

end; {uvel} Begin {Proba}

writeln (‘Исходные A и B до решения равны: ’, a:5, b:5) Uvel (a, b)

Uvel (c, b)

Writeln (‘Результат после работы процедуры:’,a:5, b:5, c:5) End. {Proba}

Решение на экране будет представлено следующим образом.

Исходные А и В до решения равны: 5 7 Удвоенные С и В процедурой в процессе решения: 10 14 Результат после работы процедуры: 10 7

Результат работы показывает следующее: параметр А описан в процедуре как параметр-переменная, а параметр В — как параметрзначение.

После окончания работы процедуры параметр А изменил начальное значение А = 5 на А = 10 только потому, что полученное значение было возвращено формальному параметру через переменную А.

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

вающей программе:

Function Log10 ( Х: Real): Real;

{функция возвращает значение десятичного логарифма числа Х} BEGIN

log10: = Ln(Х)/Ln(10) END;

Function Pwr (a,x: Real): Real;

{функция возвращает значение АХ (А в степени х (А>0)} Begin

Pwr:= Exp(x*Ln(a)); end;

Рассмотрим примеры по написанию подпрограмм.

18

Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

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

Число сочетаний из n элементов по m вычисляют по формуле

Cmn =n!/m!(n-m)!

где n, m — целые положительные числа и n > m. Алгоритм решения.

1.Вычислим n! — это числитель формулы.

2.Вычислим m!

3.Вычислим (n – m)!

4.Перемножим m! на (n – m)!, получим знаменатель формулы.

5.Разделив числитель на знаменатель, получим результат.

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

Рассмотрим два метода определения факториала заданного числа.

1. Факториал — это произведение целых чисел от 1 до n: n!=1 2 3 . . . n;

0! = 1; 1! = 1;

2! = 1 2 = 2; 3! = 1 2 3 = 6;

4! = 1 2 3 4 = 24.

Вычислить факториал можно с использованием итерационного вычисления в цикле For, начиная перемножение чисел с 1 до n включительно:

Function factI (n: byte): longint; Var

f, i: byte; Begin

19

Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

f:=1;

For i=1 to n do f:=f*i; factI:=f;

end;

2. Формулу для вычисления факториала можно записать в виде: n! = (n – 1)! n

Мы получили рекуррентную формулу для вычисления факториала, которая справедлива для всех значений n > 0.

Рекуррентная формула — это формула, которая применяется для определения членов в последовательности чисел, каждый член в которой получают умножением предыдущего на некоторое постоянное для данной последовательности выражение:

an= f(n, an−1,an−2, ... an−p).

Вычисление по рекуррентным формулам называется рекурсивным методом вычисления. Любой объект, который частично определяется через самого себя, называется рекурсивным.

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

Function fact_R (n: byte): longint; Begin

If n=1 then fact_R := 1 Else fact_R :=n*fact_R(n-1)

end;

Программа нахождения числа сочетаний будет иметь следующий вид:

Program Sochetanie_n_m;

{Вычисляет сочетания из n элементов по m} uses crt;

Var n,k,l,r:byte;

Chislitel, sochetanie_fI, sochetanie_p, sochetanie_fR, znamenatel:longint; c,d,e,s:longint;

{————}

function factorial_I(K:byte):longint; {вычисляет k! итерационным методом} var i:byte;

p:longint; begin

20

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]