Недавно добавленные исходники

•  DeLiKaTeS Tetris (Тетрис)  4 767

•  TDictionary Custom Sort  6 772

•  Fast Watermark Sources  6 559

•  3D Designer  9 502

•  Sik Screen Capture  6 892

•  Patch Maker  7 338

•  Айболит (remote control)  7 277

•  ListBox Drag & Drop  6 141

•  Доска для игры Реверси  98 001

•  Графические эффекты  7 456

•  Рисование по маске  6 752

•  Перетаскивание изображений  5 608

•  Canvas Drawing  5 986

•  Рисование Луны  5 772

•  Поворот изображения  5 228

•  Рисование стержней  3 827

•  Paint on Shape  2 984

•  Генератор кроссвордов  3 930

•  Головоломка Paletto  3 122

•  Теорема Монжа об окружностях  3 945

•  Пазл Numbrix  2 605

•  Заборы и коммивояжеры  3 407

•  Игра HIP  2 330

•  Игра Go (Го)  2 244

•  Симулятор лифта  2 646

•  Программа укладки плитки  2 214

•  Генератор лабиринта  2 755

•  Проверка числового ввода  2 371

•  HEX View  2 710

•  Физический маятник  2 397

 
скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Delphi Sources

Рекурсия и опережающее описание



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

Рассмотрим классический пример - вычисление факториала. Программа получает от компонента edinput целое число n и выводит в компонент lboutput значение N!, которое вычисляется с помощью рекурсивной функции Factorial.

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

procedure TfmExample.bbRunClick(Sender: TObject);
  function Factorial(N: Word): Extended;
  begin
    if N = 0 then
      Result: = 1 else
      Result := N * Factorial(N - 1)
  end;
var
  N: Integer;
begin
  try
    N := StrToInt(Trim(edinput.Text));
  except
    Exit; end;
  IbOutput.Caption := FloatToStr(Factorial(N))
end;

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

Рекурсивный вызов может быть косвенным. В этом случае подпрограмма обращается к себе опосредованно, путем вызова другой подпрограммы, в которой содержится обращение к первой, например:

procedure A(i: Byte);
begin
  В(i);
end;

procedure В(j: Byte);
begin
  а(j);
end;

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

procedure В(j: Byte); forward;

procedure A(i: Byte);
begin
  В(i);
end;

procedure B; begin
  A(j);
end;

Как видим, опережающее описание заключается в том, что объявляется лишь заголовок процедуры в, а ее тело заменяется стандартной директивой Forward. Теперь в процедуре а можно использовать обращение к процедуре в - ведь она уже описана, точнее, известны ее формальные параметры, и компилятор может правильным образом организовать ее вызов. Обратите внимание: тело процедуры в начинается заголовком, в котором уже не указываются описанные ранее формальные параметры.








Copyright © 2004-2025 "Delphi Sources" by BrokenByte Software. Delphi World FAQ

Группа ВКонтакте