
- •1.4 Контрольные вопросы
- •Приложение а
- •2 Символьная схема циклических алгоритмов
- •Приложение а
- •3 Символьная схема циклических алгоритмов задач, содержащие одномерные массивы
- •4 Символьная схема циклических алгоритмов задач, содержащие таблицы
- •Приложение а
- •5 Программирование линейных арифметических алгоритмов
- •5.3.4 Результаты работы распечатайте на принтере.
- •5.3.5 Оформите лабораторную работу для сдачи преподавателю.
- •Контрольные вопросы
- •Приложение a
- •7 Программирование разветвляющихся алгоритмов
- •Приложение а
- •8 Программирование циклических алгоритмов
- •Приложение а
- •9 Обработка одномерных массивов
- •Приложение а
- •10 Обработка матриц
- •Приложение а
- •11 Программирование с использованием указателей
- •Приложение а
- •12 Программирование с использованием строковых данных
- •Приложение а
- •13 Программирование с использованием переменные типа множество
- •Приложение а
- •14 Программирование с использованием переменные типа запись
- •Приложение а
- •15 Работа с файлами
- •Приложение а
- •16 Работа с текстовыми файлами
- •Приложение а
- •17 Создание и использование модулей
- •17.1 Цель работы
- •17.4 Этапы работы
- •17.4.1 Создание и использование модулей
- •17.4.2 Структура модулей
- •17.4.3 Заголовок модуля и связь модулей друг с другом
- •17.4.4 Интерфейсная часть
- •Исполняема часть
- •17. 4.6 Инициирующая часть
- •17.4.8 Доступ к объявленным в модуле объектам
- •17.4.9 Стандартные модули
- •17.4.10 Справочная информация
- •18 Программирование алгоритмов с использованием подпрограмм
- •Приложение а
- •19 Программирование алгоритмов с использованием рекурсивных подпрограмм
- •19.4. Этапы работы
- •19.4.1 Рекурсия и опережающее описание
- •19. 4.2 Расширенный синтаксис вызова функций
- •19.4.3 Решить задачу, используя рекурсивную подпрограмму
- •20 Программирование алгоритмов с использованием графического режима
- •20.4. Этапы работы
- •20.4.1 Основные понятия и средства компьютерной графики в Паскале
- •Переход в графический режим и возврат в текстовый
- •Краткая характеристика графических режимов работы дисплейных адаптеров
- •20.4.2 Использование библиотеки graph - Процедуры и функции
- •- Координаты, окна, страницы
- •- Линии и точки
- •Приложение а
19 Программирование алгоритмов с использованием рекурсивных подпрограмм
Цель работы
19.1.1 Составление программ с использованием рекурсивных подпрограмм - процедур, подпрограмм - функций
Создание библиотек подпрограмм в Паскаль
Отладка программы и контрольный просчет.
Приборы и оборудование
19.2.1 Free Pascal
19.2.2 ПЭВМ IBM PC/XT
19.2.3 Microsoft Word
19.2.4 Задание на выполнение работы в электронном варианте.
19.3 ПОРЯДОК ВЫПОЛНЕНИЯ РАБОТЫ
19.3.1 Самостоятельно изучите электронный материал.
19.3.2 Перенесите предложенные программы, используя язык программирования Free Pascal
19.3.3 Запустите программу на выполнение
19.3.4 Результаты работы распечатайте на принтере и сделайте анализ.
19.3.5 Оформите самостоятельную работу для сдачи преподавателю
19.3.6 При оформлении лабораторной работы занесите задание и результат, а также вывод от полученного результата для сдачи преподавателю
19.4. Этапы работы
19.4.1 Рекурсия и опережающее описание
Рекурсия - это такой способ организации вычислительного процесса, при котором подпрограмма в ходе выполнения составляющих ее операторов обращается сама к себе.
Рассмотрим классический пример - вычисление факториала.
Программа вводит с клавиатуры целое число N и выводит на экран значение N!, которое вычисляется с помощью рекурсивной функции РАС.
Для выхода из программы необходимо либо ввести достаточно большое целое число, чтобы вызвать переполнение при умножении чисел с плавающей запятой, либо нажать Ctrl-Z и Enter.
При выполнении правильно организованной рекурсивной подпрограммы осуществляется многократный переход от некоторого текущего уровня организации алгоритма к нижнему уровню последовательно до тех пор, пока, наконец, не будет получено тривиальное решение поставленной задачи.
В примере решение при N = 0 тривиально и используется для остановки рекурсии.
Program Factorial;
{$S+} {Включаем контроль переполнения стека}
var
n: Integer;
Function Facfn: Integer): Real;
{Рекурсивная функция, вычисляющая n ! }
begin {Fac}
if n < 0 then
WriteLn ('Ошибка в задании N')
else
if n = 0 then
Fac := 1
else Fac := n * Fac(n-l)
end {Fac} ;
{---------------}
begin {main} repeat
ReadLn (n) ;
WriteLn ('n!= ',Fac(n))
until EOF
end {main} .
Рекурсивная форма организации алгоритма обычно выглядит изящнее итерационной и дает более компактный текст программы, но при выполнении, как правило, медленнее и может вызвать переполнение стека (при каждом входе в подпрограмму ее локальные переменные размещаются особым образом организованной области памяти, называемой программным стеком). Переполнение стека особенно ощутимо сказывается при работе с сопроцессором: если программа использует арифметический сопроцессор, результат любой вещественной функции возвращается через аппаратный стек сопроцессора, рассчитанный всего на 8 уровней.
Если, например, попытаться заменить тип REAL функции FAC на EXTENDED, программа перестанет работать уже при N = 8.
Чтобы избежать переполнения стека сопроцессора, следует размещать промежуточные результаты во вспомогательной переменной.
Вот правильный вариант примера для работы с типом EXTENDED:
Program Factorial;
{$S+,N+,E+} {Включаем контроль Стека и работу сопроцессора}
var
n: Integer;
Function Fac(n: Integer): extended;
var
F: extended; {Буферная переменная для разгрузки стека сопроцессора}
{Рекурсивная функция, вычисляющая п! }
begin {Рас}
if n < 0 then
WriteLn ('Ошибка в задании N') else
if n = 0 then
Fac := 1 else begin
F := Fac(n-l) ; Fac := F * n end end {Fac} ;
{--------------}
begin {main}
repeat
ReadLn (n) ;
WriteLn ('n! = ',Fac(n))
until EOF
end {main} .
Рекурсивный вызов может быть косвенным.
В этом случае подпрограмма обращается к себе опосредованно, путем вызова другой подпрограммы, в которой содержится обращение к первой, например:
Procedure A (i : Byte) ;
begin
В (i);
.......
end ;
Procedure В (j : Byte) ;
begin
A(j);
end;
Если строго следовать правилу, согласно которому каждый идентификатор перед употреблением должен быть описан, то такую программную конструкцию использовать нельзя.
Для того, чтобы такого рода вызовы стали возможны, вводится опережающее описание:
Procedure В(j : Byte); forward;
Procedure A(i : Byte);
begin
.......
В (i) ;
.......
end ;
Procedure В;
begin
.......
A(j);
.......
end;
Как видим, опережающее описание заключается в том, что объявляется лишь заголовок процедуры В, а ее тело заменяется стандартной директивой FORWARD.
Теперь в процедуре А можно использовать обращение к процедуре В - ведь она уже описана, точнее, известны ее формальные параметры, и компилятор может правильным образом организовать ее вызов.
Обратите внимание: тело процедуры
В начинается заголовком, в котором уже не указываются описанные ранее формальные параметры.