Рекурсия
End.
Begin
Begin
Repeat
Begin
Var
Var
End.
Begin
. . .
Begin
Var
Var
Функции
End.
Begin
Begin
Var
End.
Begin
. . .
Begin
Var
Type
Процедуры
<Объявление процедуры> : : =
procedure <Имя процедуры>[(<Список формальных параметров>)];
[<Разделы объявления локальных типов, констант, переменных>]
[<Разделы объявления локальных процедур и функций>]
begin | } Раздел исполнения процедуры |
<Операторы> | |
end; |
<Список формальных параметров> : : =
<Элемент списка 1>; <Элемент списка 2>; . . .
<Элемент списка> : : =
<Список имён параметров-значений>: <Тип>
или
var <Список имён параметров-переменных>: <Тип>
или
const <Список имён параметров-констант>: <Тип>
<Обращение к процедуре> : : =
<Имя процедуры>[(<Список фактических параметров>)]
Замечание. Фактические параметры должны быть совместимы с формальными по типам.
Пример программы 2.
program Example2;
MyInt = integer ;
I: MyInt ;
J: integer;
procedure P2(var M: integer);
end;
P2(J) ; // Нормально
P2(I) ; // Ошибка
Пример программы 3.
program Example3;
I, J, K : integer;
procedure P3(L : integer; var M : integer; const N : integer);
Inc(L) ; // Бесполезно
Inc(M) ; // Полезно
(* Inc(N) ; *) // Ошибка
end;
I := 1; J := 1; K := 1;
P3(I, J, K) ;
wri teln(‘I=’, I) ; // I = 1
wri teln(‘J=’, J) ; // J = 2
<Объявление функции> : : =
function <Имя функции>[(<Список формальных параметров>)] :
<Тип возвращаемого значения>;
<Разделы объявления локальных типов, констант, переменных>
<Разделы объявления локальных процедур и функций>
begin | } Раздел исполнения процедуры |
<Операторы> | |
end; |
Среди <Операторов> должен быть хотя бы один «Оператор» вида
<Имя функции> := <Выражение> ;
или
result := <Выражение> ;
Пример программы 4.
program Example4;
x, y, Eps : Double;
function BesselI0(x, Eps : Double) : Double ;
S, A, B, R: Double ;
BesselI0 := S ;
end;
writeln(‘x=? ’) ; readln(x);
writeln(‘Eps=? ’) ; readln(Eps);
y := BesselI0(x, Eps) ; writeln(‘y=’, y) ;
x,y: Double;
function BesselI0(x, eps : Double): Double;
I, N: integer;
T, A, B, R, x2: Double;
x2 := sqr(x/2) ;
A := x2 ;
N := 0 ;
B := x2 / (N + 2) / (N + 2) ;
inc(N);
A := A * B ;
B := x2 / (N + 2 ) / (N + 2) ;
R := A / (1 - B) ;
until ( B < 1) and ( R < eps ) ;
T := 1;
for I := N downto 1 do
T := 1 + x2 / I / I * T ;
BesselI0 := T ;
end ;
x := 3 ;
y := BesselI0(x, 1e-20) ;
writeln(y) ;
readln ;
end.
writeln(‘Введите x’) ; readln(x) ;
writeln(‘Введите eps’) ; readln(eps) ;
if (eps <= 0) or (eps >= 1) then exit ;
writeln(‘f=’, BesselI(x, Eps));
readln;
Оконное приложение в среде Lazarus:
Текст кода в среде Lazarus:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit; Edit2: TEdit; Edit3: TEdit;
Label1: TLabel; Label2: TLabel; Label3: TLabel;
procedure Button1Click(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
function BesselI0(x, eps : Double): Double;
var
. . .
begin
. . .
end;
procedure TForm1.Button1Click(Sender: TObject);
var
x, y, eps: double;
begin
x := StrToFloat(Edit1.Text);
eps := StrToFloat(Edit2.Text);
y := BesselI0(x, eps);
Edit3.Text := FloatToStr(y);
end;
end.
Оконное приложение в среде Visual C++, фрагмент кода:
double BesselI0(double x, double eps)
{
int i, N;
double T, A, B, R, x2;
x2 = (x / 2.0)*(x / 2.0) ;
A = x2 ;
N = 0 ;
B = x2 / ((double)N + 2.0) / ((double)N + 2.0) ;
do
{
N++;
A *= B ;
B = x2 / ((double)N + 2.0) / ((double)N + 2.0) ;
R = A / (1 - B) ;
}
// while (!( B < 1 && R < eps )) ;
while (B >= 1 || R >= eps);
T = 1.0;
for (i = N; i >= 1; i--)
T = 1.0 + x2 / ((double)i * (double)i) * T;
return T;
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
double x;
x = System::Convert::ToDouble(textBox1->Text);
double eps;
eps = System::Convert::ToDouble(textBox2->Text);
double y;
y = BesselI0Aux(x, eps);
textBox3->Text=System::Convert::ToString(y);
}
При решении сложных задач программирования эти задачи разбиваются на более простые подзадачи. Каждая из подзадач, в свою очередь, может быть разбита на еще более простые подзадачи, и т.д. Если задача в ходе такого последовательного разбиения свелась (необязательно за один шаг) сама к себе самой, имеет место рекурсия.
Если задача сводится к себе, и еще раз к себе, и так далее, то количество обращений к себе должно быть конечным.
Каждое очередное сведение задачи к себе должно приближать задачу к тривиальному случаю. В тривиальном случае задача решается по алгоритму, который более не сводит задачу к себе.
Рекурсия используется во множестве стандартных алгоритмов. Далее, в курсе лекций, тема «Рекурсивные алгоритмы» будет возобновляться многократно.
Пример.
Применяя сведение задачи к себе n раз, можно «дойти» до тривиального случая – до значения 0!, а оно равно 1.
Пример 2.
Применение такого сведения задачи к себе приводит к «зацикливанию».
Числа Фибоначчи выражаются «сами через себя» при
, но выражаются явно (дают тривиальный случай) при
и
:
,
,
,
.
,
– Golden Ratio.
Сумма убывающей геометрической прогрессии
,
,
есть функциональный (а именно, степенной, по степеням переменной ) ряд с коэффициентами 1, 1, … .
Полиномы Фибоначчи являются коэффициентами разложения в степенной ряд функции
,
.
Полиномы Фибоначчи выражаются «сами через себя» при
, но выражаются явно (дают тривиальный случай) при
и
:
,
,
Связь с числами Фибоначчи:
Пример рекурсивной функции
functionFib(n: integer; x: double): double;