Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Прогр.на_ЯВУ_уч.пос.DOC
Скачиваний:
24
Добавлен:
01.07.2025
Размер:
2 Мб
Скачать
☆

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

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

Общее описание процедурного типа следующее:

Type <имя типа>=Function (<список параметров>):<тип>;

Type <имя типа>=Procedure (<список параметров>);

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

  1. Подпрограмма, присваиваемая процедурной переменной, должна быть оттранслирована в режиме дальнего типа вызова (см. пример ниже).

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

  3. Данные подпрограммы не могут быть вложенными в другие подпрограммы.

  4. Такие подпрограммы не могут быть процедурами прерываний.

Пример использования подпрограмм

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

.

Вычисление производится по формуле

,

где , ,

количество отрезков разбиения площади интегрирования определяется по заданной точности  = 10-3. Сначала интеграл представляется в виде одной трапеции, потом двух, потом четырех и т.д., то есть шаг интегрирования в каждом цикле уменьшается в два раза.

Program SumInt;

{ Демонстрационная программа на использование функций: вычисление суммы двух интегралов методом трапеций с заданной точностью }

Const EPS=1E-3; { Точность зададим константой }

Type Func=Function(x:real):real; { процедурный тип }

Var SI:Real; { Результат: сумма интегралов }

{ Сначало опишем подпрограммы с использованием дальнего вызова, которые будут передаваться в подпрограмму как параметры }

{$f+}

Function F1(x:real):real;

Begin

F1:=exp(-x)*(x*x+7*x+9)

End;

Function F2(x:real):real;

Begin

F2:=sin(x)*(x*x*x+3)

End;

{$f-}

{ В функцию передаем границы (вещественные) и последовательность вычислений – процедурный тип }

Function IntTrap(A,B:Real;F:Func):real;

Var IntAlt,IntNew, { старое и новое значение интеграла }

H,S,x,

v:real; { вспомогательная переменная }

Begin

H:=B-A;

v:=F(A)+F(B); { для сокращения вычислений }

IntNew:=H/2*v; { Первый интеграл из одной трапеции }

Repeat

IntAlt:=IntNew; { Старим предыдущее значение }

H:=H/2; { Уменьшаем шаг в 2 раза }

S:=0; x:=A;

Repeat

x:=x+H;

S:=S+F(x)

Until x>=B;

IntNew:=H/2*(v+2*S);

Until Abs(IntAlt-IntNew)<EPS; { Проверка, насколько мала разность интегралов, вычисленных с разным шагом }

IntTrap:=IntNew;

End;

{ Раздел операторов – непосредственно сама программа }

Begin

{ Очень важно соблюдать типы и последовательность параметров при обращении к функциям}

SI:=IntTrap(0.0,2.0,F1)+IntTrap(0.0,2.0,F2);

Writeln('Сумма интегралов=',SI:7:3)

End.