- •ПРЕДИСЛОВИЕ
- •1.1. История и классификация языков программирования высокого уровня
- •1.2. Первое (знакомство с Паскалем
- •Задания
- •Лекция 2
- •2.1. Некоторые сведения о системе ТУрбо-Паскаль
- •2.2. Способы описания языка программирования
- •Лекция 3
- •3.2. Типы данных
- •4.1. Структура Паскаль-программы
- •4.2. Арифметические операции, функции, выражения Арифметический оператор присваивания
- •Форматы процедуры write
- •Задания
- •1. Что будет напечатано программой
- •если последовательно вводятся три числа: 36, -6, 2345?
- •5.2. Функции, связывающие различные типы данных
- •Задания
- •Теперь посмотрим, как это программируется наТЛаскале.
- •Здесь
- •<параметр цикла>::= <имя простой переменной порядкового типа>
- •Задания
- •7.1. Подпрограммы-процедуры
- •7.2. Подпрограммы-функции
- •7.4. Рекурсивные подпрограммы
- •8.1. Что такое рекуррентная последовательность
- •8.2. Программирование вычислений рекуррентных последовательностей
- •Задания
- •Задания
- •6. Вывод результата.
- •Теперь будем составлять подпрограммы.
- •Задания
- •12.2. Операции над множествами
- •12.3. Примеры использования множеств
- •Красивая программа! К сожалению, ею нельзя воспользоваться для
- •В этой программе использована функция определений размера файла:
- •.Fiiesize(<HMH файловой переменной>);
- •Задания
- •14.2. Работа с файлами записей
- •Задания
- •15.2. Связанные списки
- •Лекция 16
- •16.1. Организация внешних подпрограмм
- •16,2. Создание и использование модулей
- •распечаткой текста программы с подробными комментариями.
- •выполнения следующих операции над обыкновенными дробями вида -q
- •(Р — целое, Q — натуральное):
- •1) сложение;
- •2) вычитание;
- •3) умножение;
- •4) деление;
- •5) сокращение дроби;
- •7) функции, реализующие операции отношения (равно, не равно,
- •Используя этот модуль, решить задачи:
- •При разработке модуля рекомендуется такая последовательность
- •Задания
- •Приведем текст программы целиком.
- •ЗАДАНИЯ ПО ТЕМЕ “ЛИНЕЙНЫЕ АЛГОРИТМЫ”
- •ЦЕЛОЧИСЛЕННАЯ АРИФМЕТИКА
- •Сортировка массивов
- •ЗАДАЧИ ПО ТЕМЕ “ОБРАБОТКА СТРОК”
- •ЗАДАНИЯ ПО ТЕМЕ “МОДУЛИ”
- •ЗАДАНИЯ ПО ТЕМЕ “ДИНАМИЧЕСКИЕ ПЕРЕМЕННЫЕ”
- •Задачи, предлагавшиеся на школьных олимпиадах по программированию (Пермская область)
- •Учебное издание
Далее разговор пойдет о ситуации на первый взгляд совершенно парадоксальной. Оказывается, подпрограмма в своем описании может содержать обращение к самой себе. Такая подпрограмма называется рекурсивной.
7.4.Рекурсивные подпрограммы
Вматематике рекурсивным называется определение любого поня тия через самого себя. Классическим примером является определение факториала целого числа, большего или равного нулю.
. |
Г1, |
если 7Т= О, |
ть ” |
< |
если п > 0. |
|
\ п (п -1 )!, |
Здесь функция факториал определена через факториал. Нетрудно по нять справедливость такого определения. Для п > 0:
п |
п—1 |
гг! = П i = |
1 *2 х х (п - 1) •гг = п •Д г = п(п - 1)! |
i=i |
i=i |
Вариант 0! = 1 |
является тривиальным. Но это ’’ опорное” значе |
ние, от которого начинается раскручивание всех последующих значе ний факториала:
1! = 1 *0! = 1 •1 = 1; 2! = 2-1! = 2; 3! = 3 2! = 6 и т.д.
Рассмотрим подпрограмму-функцию, использующую в своем опи сании приведенную выше рекурсивную формулу.
Function Factor(N Pozlnt) Pozlnt;
Begin
I f N=0
Then Factor :a 1
Else Factor := N * Factor(N - 1)
End;
Предполагается, что тип Pozlnt объявлен глобально следующим обра зом:
Type Pozlnt * 0..MaxInt;
Пусть в основной программе для вычисления в целой переменной л значения 3! используется оператор
При вычислении функции с аргументом 3 произойдет повторное об ращение к функции Factor(2). Это обращение потребует вычисления F a ctor(l). И наконец, при вычислении Fact or (0) будет получен число вой результат 1. Затем цепочка вычислений раскрутится в обратном порядке:
F a cto r(l) |
= 1 |
* |
Factor(O) |
■ |
1 |
|
F actor(2) |
■ |
2 |
* |
F actor(l) |
® |
2 |
F actor(3) |
= |
3 |
* |
Factor(2) |
= 6. |
Последовательность рекурсивных обращений к функции должна обя зательно выходить на определенное значение. А весь маршрут после довательных вхождений машина запоминает в специальной области памяти, называемой стеком.Таким образом, выполнение рекурсивной функции происходит в два этапа: прямой ход — заполнение стека; об ратный ход — цепочка вычислений по обратному маршруту, сохранен ному в стеке.
Использование рекурсивных функций - красивый прием с точки зрения программистской эстетики. Однако этот путь не всегда самый рациональный. Рассмотренную задачу с а! можно решить так:
F := |
1; |
|
For I |
:* 1 |
То N Do |
F |
F * |
I; |
Очевидно, что такой вариант программы будет работать быстрее, чем рекурсивный. И в том случае, когда важнейшим является сокращение времени выполнения программы, следует отдать предпочтение после днему варианту.
В каждой конкретной реализации Паскаля имеется ограничение на количество рекурсивных обращений к подпрограмме (глубине рекур сии). Это связано с ограничением на размер стека. По этой причине можно попасть в ситуацию, когда рекурсивной подпрограммой вообще не удастся воспользоваться.
Рекурсивно определена может быть не только функция, но и проце дура. Рассмотрим еще одну классическую задачу, известную в лите ратуре под названием ’’Ханойская башня” .
На площадке (назовем ее А) находится пирамида, составленная из дисков уменьшающегося размера от основания к вершине.
(x i=- 0) и целого п, которая вычисляет величину хп согласно формуле
|
1 |
при п = 0, |
хл |
1 |
при п < 0, |
— |
||
|
х хп~1 |
при п > 0. |
6. Даны натуральные числа п и т ; найти НОД(п, т ) . Использовать программу, включающую рекурсивную процедуру вычисления НОД, основанную на соотношении НОД(п,т) = И ОД(т,г), где г — остаток от деления п на т.