Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
УМК ОАиП.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
1.14 Mб
Скачать

Параметры процедурного типа

Все рассмотренные параметры подпрограмм позволяли выполнять один и тот же алгоритм с различными данными. В Паскале есть и другая возможность — параметризовать алгоритм функциями и процедурами. Это может пригодиться, если требуется выполнить одну и ту же последовательность действий, внутри которой выполняется обращение к разным функциям или процедурам.

Описание параметра подпрограммы в большинстве случаев состоит из имени и типа. Имя функции является константой процедурного функционального ) типа, который требуется описать в разделе type, например:

type fun = function(x : real) : real;

pr = procedure;

proc = procedure(a, b : word; var c : word);

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

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

на интервале [a, b] с заданным количеством его разбиений (пример 4.5).

program integrals;

type fun = function(x : real) : real; { 1 }

var a, b : real;

n : integer;

{$F+}

function Q(x : real) : real;

begin

Q := 2 * x / sqrt(1 – sin(2 * x));

end;

function R(x : real) : real;

begin

R := cos(x) – 0.2 * x;

end;

{$F–}

function integr(f : fun; a, b : real; n : integer) : real;

var sum, x, h : real;

i : integer;

begin

h := (b – a) / n; sum := 0; x := a;

for i := 1 to n do begin

sum := sum + f(x); x := x + h;

end;

integr := sum * h;

end;

begin

writeLn('Введите интервал и количество шагов');

readln(a, b, n);

writeln('Интеграл для первой функции: ', integr(Q, a, b, n):8:3);

writeln(' Интеграл для второй функции: ', integr(R, a, b, n):8:3);

end.

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

Итак, чтобы передать имя функции или процедуры в подпрограмму, необходимо:

  1. Определить соответствующий процедурный тип.

  2. Задать для функций и процедур, предназначенных для передачи в подпрограмму, ключ компилятора {$F +}, определяющий дальнюю адресацию. При этом компилятор формирует полный адрес, состоящий из сегмента и смещения. Альтернативный способ — указать в заголовке каждой функции директиву far:

function Q(x : real) : real; far;

Рекурсивные подпрограммы

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

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

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

Простой пример рекурсивной функции — вычисление факториала (это не означает, что факториал следует вычислять именно так). Чтобы получить факториал числа 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;

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

Достоинством рекурсии является компактная запись. К недостаткам относятся расход времени и памяти на повторные вызовы функции и передачу ей параметров, а главное, опасность переполнения стека.

Модули

Модуль — это подключаемая к программе библиотека ресурсов. Он может содержать описания типов, констант, переменных и подпрограмм. В модуль обычно объединяют связанные между собой ресурсы: например, в составе оболочки есть модуль Graph для работы с экраном в графическом режиме. Модули применяются как библиотеки, которые могут использоваться различными программами, и для разбиения сложной программы на составные части.

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]