Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Все вопросы..docx
Скачиваний:
11
Добавлен:
25.09.2019
Размер:
158.31 Кб
Скачать

9. Побочный эффект в процедурах и функциях.

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

Пример.

program Pob_effecy;

var a,b,c: byte;

function max (var x,y,z:byte): byte;

begin

if x<y then x:=y;

if x<z then max:=z

else max:=x;

end;

begin

readln (a,b,c);

writeln (a+max(a,b,c));

readln (a,b,c);

writeln (max(a,b,c)+a);

end.

Чтобы предотвратить малый ПЭ нужно, создать алгоритм без последующих присваиваний. Нужно описать глобальную N и внутри функции наращивать ее на 1, тогда основная программа будет знать, сколько раз обращались к функции.

Борьба с побочным эффектом:

1)Убрать левый пар-р. A[i,j]:=...(оператор присваивания)

2)Использовать const для предотвращения поб.эффекта.

procedure m(const mas:T;var max,min: byte);

mas[i,j]:=...нельзя делать, потому что она const.

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

Параметры константы не могут быть преданы в другие процедуры.

Даже выражение не может иметь файловой компоненты.

10)Рекурсия

Описание процедуры или функции распространяется на саму себя, поэтому может быть вызвано в теле самой процедуры - это называется само активация или рекурсия.

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

Рассмотрим пример с факториалом:

1,если N=0

N(N-1)!,иначе

Program factorial;

Var n:byte;

Function factor(x:byte):real;

Begin{Для функции}

If(x=0) then factor:=1

Else factor:=x*factor(x-1);{По этой формуле будем делать свертку * }

End;{для функции}

Begin{Основной программы}

Readln(n);

Writeln(Factor(n):20:1);

End.

Механизм действия рекурсивного вызова:

N - фактический параметр.

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

Разворачивание СТЕКа:

1

Fac(x):

0

3

4

2

1

X:

4

N:

Механизм сворачивания стека.

6

2

1

1

24

3

2

1

0

4

4

На конечном шаге получим результат Factor. По формуле * переходим к предыдущему вызову. В это же время последний блок перестал существовать. Х перестает быть формальным параметром. Остался только входной параметр(4)и результат fact(4)=24.

Ограничения на глубину рекурсии:

-Формально нет, но косвенно всегда кол-во вызова определяется объемом стека.

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

-Глубина рекурсии зависит от фактического параметра,(если была бы 3,то глубина была бы меньше). Глубина рекурсии определяется значением фактического и размером формального параметра.

Шаг рекурсии: тот оператор, в котором существует само вызов. Может осуществляется лишь в условном операторе.

Рекурсивный алгоритм можно заменить итерационным, но никак наоборот.