
- •Алфавит и лексемы
- •Константы
- •Имена, ключевые слова и знаки операций
- •Ввод с клавиатуры
- •Вывод на экран
- •Условный оператор if
- •Оператор варианта case
- •Цикл с предусловием while
- •Цикл с постусловием repeat
- •Цикл с параметром for
- •Рекомендации по использованию циклов
- •Оператор перехода goto
- •Перечисляемый тип данных
- •Интервальный тип данных
- •Двумерные массивы
- •Операции
- •Процедуры и функции для работы со строками
- •Множества
- •Операции над множествами
- •Подпрограммы для работы со всеми типами файлов Процедуры
- •Функции
- •Текстовые файлы
- •Бестиповые файлы
- •Компонентные файлы
- •Прямой доступ
- •Процедуры
- •Функции
- •Глобальные и локальные переменные
- •Параметры-значения
- •Параметры-переменные
- •Параметры-константы
- •Нетипизированные параметры
- •Открытые массивы и строки
- •Рекурсивные подпрограммы
- •Описание модулей
- •Использование модулей
- •Модуль System
- •Модуль Crt
- •Работа с экраном
- •Работа с клавиатурой
- •Модули Dos и WinDos
- •Модуль Graph
- •Структура графической программы
- •Модуль Strings
Открытые массивы и строки
Открытый массив может быть только одномерным и состоять из элементов любого типа, кроме файлового. На место открытого массива можно передавать одномерный массив любой размерности, состоящий из элементов такого же типа. Передавать открытый массив можно как значение, переменную или константу, например:
procedure P(a : array of real);
Элементы массива нумеруются с нуля. Номер максимального элемента в массиве можно определить с помощью функции High.
Пример #3. |
|
|
Функция, определяющая максимальный элемент любого целочисленного массива. |
function max_el(const mas : array of integer) : integer; var i, max : integer; begin max := mas[0]; for i := 0 to High(mas) do if mas[i] > max then max := mas[i]; max_el := max; end;
|
Для передачи в подпрограмму по адресу строк любой длины используется либо специальный тип OpenString, называемый открытой строкой, либо тип string при включенном режиме {$P+} (по умолчанию этот режим выключен).
Пример #4. |
Пример передачи строк в подпрограмму: type s20 = string[20]; var s1 : string[40]; s2 : string[10]; procedure P(const x : s20; y : string; var z : openstring); ... begin ... P(s2, s1, s1); ... end.
|
Рекурсивные подпрограммы
Рекурсивной называется подпрограмма, в которой содержится обращение к самой себе. Такая рекурсия называется прямой. Есть также косвенная рекурсия, когда две или более подпрограмм вызывают друг друга.
При обращении подпрограммы к самой себе происходит то же самое, что и при обращении к любой другой функции или процедуре: в стек записывается адрес возврата, резервируется место под локальные переменные, происходит передача параметров, после чего управление передается первому исполняемому оператору подпрограммы.
Для завершения вычислений каждая рекурсивная подпрограмма должна содержать хотя бы одну ветвь алгоритма, заканчивающуюся возвратом в вызывающую программу.
Пример #5. |
Простой пример рекурсивной функции - вычисление факториала. Чтобы получить значение факториала числа n, требуется умножить на n факториал числа (n - 1). Известно также, что 0! = 1 и 1! = 1. function fact(n : byte) : longint; begin if (n = 0) or (n = 1) then fact := 1 else fact := n * fact(n - 1); end;
Рассмотрим, что происходит при вызове этой функции при n = 3. В стеке отводится место под параметр n, ему присваивается значение 3 и начинается выполнение функции. Условие в операторе if ложно, поэтому управление передается на ветвь else. Для вычисления выражения n * fact(n - 1) требуется повторно вызвать функцию fact. Для этого в стеке отводится новое место под параметр n, ему присваивается значение 2, и выполнение функции начинается сначала. В третий раз функция вызывается со значением параметра, равным 1, и вот тут-то становится истинным выражение (n = 0) or (n = 1), поэтому происходит возврат из подпрограммы в точку вызова, то есть на выражение n * fact(n - 1) для n = 2. Результат выражения присваивается имени функции и передается в точку ее вызова, то есть в то же выражение, только теперь происходит обращение к параметру n, равному 3. |
Достоинством рекурсии является компактная запись, а недостатками - расход времени и памяти на повторные вызовы функции и передачу ей параметров, а, главное, опасность переполнения стека.
Лекция 16
Модули
Модуль - это подключаемая к программе библиотека ресурсов. Он может содержать описания типов, констант, переменных и подпрограмм. В модуль обычно объединяют связанные между собой ресурсы: например, в составе оболочки есть модуль Graph для работы с экраном в графическом режиме.
Модули применяются либо как библиотеки, которые могут использоваться различными программами, либо для разбиения сложной программы на составные части.
Использование модулей позволяет преодолеть ограничение в один сегмент на объем кода исполняемой программы, поскольку код каждого подключаемого к программе модуля содержится в отдельном сегменте.
Модули можно разделить на стандартные, которые входят в состав системы программирования, и пользовательские, то есть создаваемые программистом. Чтобы подключить модуль к программе, его требуется предварительно скомпилировать. Результат компиляции каждого модуля хранится на диске в отдельном файле с расширением .tpu.