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

Табулирование функций

Табулирование – построение таблицы значений:

x

y

 

 

 

Расчет значения

0.01

5.56

 

x[1]:=a

x[1]:=a

аргумента требует

 

 

 

больше времени

0.02

6.34

 

 

 

 

 

 

 

0.03

7.56

 

i:=1,N

i:=1,N

 

...

 

 

 

 

 

Рассчитыва-

y[i]:= f(x[i])

y[i]:= f(x[i])

 

 

 

x[i]:= a+h*(i-1)

ется лишний

 

 

 

 

 

N+1 элемент

x[i+1]:= x[i]+h

нет

 

i<>N

 

 

 

 

 

 

 

 

 

да

y[i]:= f(x[i])

 

 

 

 

 

 

 

Исключение

x[i+1]:= x[i]+h

 

 

 

 

 

 

 

расчета лишнего

 

 

 

 

элемента за счет

 

 

 

 

дополнительной

 

 

 

 

 

проверки

 

31

Подпрограмма табулирования функции

Unit SFun;

Interface

Type func=function(x:Single):Single; Procedure TabFun(f:func;a,b:Single;n:integer;

var Masf,MasX:array of Single);

Implementation Procedure TabFun; Var h,x:Single; i:integer; Begin

h:=(b-a)/(n-1); for i:=0 to n-1 do

begin MasX[i]:= a+h*i; Masf[i]:=f(MasX[i]);

end;

End;

End.

32

Тестирующая программа

Program Ex4_9; {$APPTYPE CONSOLE} Uses SysUtils,

SFun in 'SFun.pas';

Var masF1,masX1:array[1..10] of Single; masF2,masX2:array[1..20] of Single; i:integer;

function F1(x:Single):Single; Begin

F1:=sin(x);

end;

function F2(x: Single):Single; Begin

F2:=exp(x)+cos(x);

end;

33

Тестирующая программа. Раздел операторов

Begin TabFun(F1,0,2,10,masF1,masX1);

WriteLn(’Table 1’); for i:=1 to 10 do

WriteLn(masX1:4:1,masF1[i]:7:1);

WriteLn(’Table 2’);

TabFun(F2,0,2,20,masF2,masX2); for i:=1 to 20 do

WriteLn(masX2:4:1,masF2[i]:7:1);

ReadLn;

End.

34

4.4 Рекурсия

4.4.1 Основные понятия

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

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

Косвенная рекурсия требует предопределения forward:

A

 

B

 

 

 

 

 

 

procedure B(j:byte);

 

 

 

 

 

 

 

 

 

forward;

 

 

 

procedure A(j:byte);

 

B(i)

 

A(j)

begin

...B(i);...

 

 

end;

 

 

 

 

 

 

 

 

 

 

procedure B;

 

 

 

 

begin

... A(j);...

 

 

 

 

end;

 

35

 

 

 

 

 

Вычисление наибольшего общего делителя

Базисное утверждение: если

 

 

Nod(A,B,R)

 

 

 

 

 

 

 

 

 

 

два числа равны, то их

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

наибольший общий

да

 

 

 

 

 

 

 

нет

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

делитель равен этим

 

 

A=B

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

да

 

 

 

 

 

 

нет

числам.

 

 

 

 

 

 

A>B

R=A

 

Рекурсивное утверждение:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

наибольший общий

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Nod

 

 

 

 

 

 

Nod

 

 

 

 

 

 

 

 

 

 

 

 

 

 

делитель двух чисел равен

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(A-B,B,R)

 

 

 

 

 

(A,B-A,R)

 

наибольшему общему

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

делителю их разности и

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Return

 

 

 

 

 

 

 

 

 

 

меньшего из чисел.

 

 

 

 

 

 

 

 

 

 

 

 

 

a

 

@r

 

 

18

Фрейм активации

 

6

b

 

12

6

 

 

@r

Фрейм активации

 

 

r

 

12

 

6

6

 

 

@r

 

 

 

Фрейм активации

 

 

12

 

 

18

36

 

 

 

Вычисление наибольшего общего делителя (2)

Program Ex4_10a;

{$APPTYPE CONSOLE} Uses SysUtils; Var a,b,r:integer;

Procedure nod(a,b:integer; var r:integer); Begin

if a=b then r:=a

else if a>b then nod(a-b,b,r)

 

else nod(a,b-a,r)

End;

 

Begin

WriteLn('Input A,B');

 

ReadLn(a,b);

 

nod(a,b,r);

 

WriteLn(r);

 

ReadLn;

End.

37

Вычисление наибольшего общего делителя (3)

 

 

 

Nod(A,B)

 

 

 

 

 

 

 

 

да

 

 

 

 

 

 

нет

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

A=B

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

да

 

A>B

нет

Result = A

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Result =

 

 

 

Result =

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Nod(A-B,B)

 

 

Nod(A,B-A)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Return

 

a

6

Фрейм активации

18

6

 

b

 

 

Фрейм активации

12

12

r

6

 

 

 

6

12

Фрейм активации

 

18

38

 

 

Вычисление наибольшего общего делителя (4)

Program Ex4_10b;

{$APPTYPE CONSOLE} Uses SysUtils; Var a,b,r:integer;

Function nod(a,b:integer):integer; begin if a=b then Result:=a

else

if a>b then Result:=nod(a-b,b) else Result:=nod(a,b-a)

end;

Begin WriteLn('Input A,B'); ReadLn(a,b); r:=nod(a,b); WriteLn(r);

ReadLn;

End.

39

4.4.2 Фрейм активации.

Структура рекурсивной подпрограммы

Каждое обращение к рекурсивной подпрограмме вызывает независимую активацию этой подпрограммы.

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

Фрейм активации включает

локальные переменные подпрограммы;

копии параметров-значений;

адреса параметров-переменных и параметров-констант (4 байта);

копию строки результата (для функций типа string);

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

40

Соседние файлы в папке ОП. Лекции