ЛР1 - Процедурные типы
Лабораторная работа №1
Процедурные типы
Цель работы – овладение практическими приемами разработки программ с помощью процедурных типов, дающих программисту гибкие средства передачи функций и процедур в качестве фактических параметров при обращении к другим процедурам и функциям.
1. Теоретические сведения
Для объявления процедурного типа используется заголовок процедуры (функции), в котором опускается ее имя, например:
Type
Proc1 = Procedure (a, b, c : real; var d: real);
Proc2 = Procedure ( var a, b);
Рекомендуемые материалы
Proc3 = Procedure;
Func1 = Function : string;
Func2 = Function ( var s: string) : real;
Как видно из приведенных примеров, существует два процедурных типа:
тип-процедера и тип-функция.
Рассмотрим пример, иллюстрирующий механизм передачи процедур в качестве фактических параметров вызова. Программа выводит на экран таблицу двух функций: sin1(x) = (sin(x) + 1) * e-x
и cos1(x) = (cos(x) + 1) * e-x.
Вычисление и печать значений этих функций реализуется в процедуре PrintFunc, которой в качестве параметров передаются номер позиции N на экране, куда будет выводиться очередной результат (с помощью этого параметра реализуется вывод в две колонки), и имя нужной функции.
Пример 1.1
Program VichFunc;
Uses Crt;
Type Func = Function (x: real) : real;{объявление процедурных типов: типа функций}
{$F+}; {включение директивы “дальнего” вызова}
Function sin1(x:real): real;
begin
sin1 := (sin(x)+1) * exp(-x);
end;
Function cos1(x:real): real;
begin
cos1 := (cos(x)+1) * exp(-x);
end;
{$F-};
Procedure PrintFunc(n: byte; F: Func);{вычисление и печать значений функций реализуется в данной процедуре, в которой в качестве параметра передается номер позиций n на экране, куда будет выводиться очередной результат (с помощью этого параметра реализуется вывод в две колонки), и имя нужной функции}
const np=5; {количество вычислений функций}
Var x: real; i: integer;
Begin
for i:=1 to np do
begin
x:= i * (2 * 3.14/np);
GotoXY(n,whereY);{перемещаем курсор к элементу экрана с координатами Х,У., whereY – возвращает текущую координату Yтекущего положения курсора в окне}
writeln (x:5:3; F(x):10:5);
end;
End;
Begin {Основная программа}
ClrScr;
PrintFunc(1,sin1);
GotoXY(1,1);
PrintFunc(35,cos1);
KeyPressed;
End.
Обратим внимание: для установления правильных связей функций sin1 и cos1 с процедурой PrintFunc они должны компилироваться с расчетом на дальнюю модель памяти. В этом режиме при вызове подпрограмм используются длинные 4-байтовые адреса (для записи адреса в память отдельно сохраняется сегментный адрес = 2 байтам, и смещение = 2 байтам). 2-х байтовые адреса применяются обычно для адресации подпрограмм, объявленных в основной программе или ее подпрограмма.
Вот почему в программе вставлены ключи компилятору {$F+ }либо вставляются стандартные функции Far сразу за заголовками функций. В таком режиме должны компилироваться любые процедуры и функции, которые будут передаваться в качестве фактических параметров вызова.
Стандартные (встроенные) процедуры и функции ТР не могут передаваться рассмотренным способом.
В программе могут быть объявлены переменные процедурных типов, например, так:
Var
P1 : Proc1;
f1,f1: Func2;
ap: array [1..N] of Proc2;
Переменным процедурных типов допускается присваивать в качестве значений имена соответствующих подпрограмм. После такого присваивания имя переменной становится синонимом имени подпрограммы, например:
Type
Proc = Procedure ( n: word; var a : byte);
Var
ProcVar : Proc;
X, Y : byte;
Procedure Proc1 (x : word; var y : byte); far;
begin
if x > 255 then y:= x mod 255 else y := byte (x)
end;
begin
ProcVar := Proc1;
for x := 150 to 180 do
begin
ProcVar (x + 100, y);
Write ( y : 8)
end
end.
Разумеется, такого рода присваивания допустимы и для параметров-функций, например:
Type
FuncType = Function ( i : integer) : integer;
Var
VarFunc : FuncType;
i : integer;
Function MyFunc ( count : integer) : integer; far;
begin
…….
end; {MyFunc}
begin {Основная программа}
……..
i : MyFunc ( i ); {Обычное использование результата функции}
……
VarFunc := MyFunc;{Присваивание переменной процедурного типа
имени функции MyFunc}
……
Отметим, что присваивание VarFunc:= MyFunc(1) будет недопустимым, так как слева и справа от знака присваивания используются несовместимые типы: слева – процедурный тип , а справа – Integer; имя функции со списком фактических параметров MyFunc(1) трактуется ТР как обращение к значению функции, в то время как имя функции без списка параметров рассматривается как имя функции.
Отличие от стандартного Паскаля, в ТР разрешается использовать в передаваемой процедуре (функции) как параметры-значения, так и параметры-переменные.
Основное предназначение процедурных типов – дать программисту гибкие средства передачи функций и процедур в качестве фактических параметров обращения к другим процедурам и функциям.
2.Задачи для самостоятельного решения
Задача 1.Разработать подпрограмму, которая возвращает массив значений произвольной функции при заданных интервале изменения аргумента [a,b] и количество точек n.
Задача 2.Разработать процедуру определения корня функции на заданном отрезке. Поместить процедуру в модуль. Разработать тестирующую программу.
Задача 3.Разработать подпрограмму, которая определяет корни уравнения y = x2 – 2 на заданном отрезке методом половинного деления.
Задача 4. Разработать программу с использованием подпрограммы-функции. Вычислить
Z = (Xm + Ym) / 2.
Xm ,Ym – наименьшие элементы массивов Х(25) и У(25).
Задача 5. Разработать программу с использованием подпрограммы-функции. Подсчитать число нулевых элементов для матриц А(m,n) и В(k,l).
Задача 6. Разработать программу с использованием подпрограммы-функции. Вычислить среднее арифметическое положительных элементов для массивов А(n), B(m), C(k).
Задача 7. Разработать программу с использованием подпрограммы-функции. Вычислить
Z = (V1 + V2 + V3) / 3.
V1,V2,V3 – объемы шаров с радиусами R1,R2,R3. Объемы вычислять в подпрограмме.
Задача 8. Выполнить на ПЭВМ программу с использованием подпрограммы-функции. Вычислить сумму положительных элементов для массивов X(N), Y(M), Z(К).
Задача 9. Cоставить подпрограмму-функцию TRAP для вычисления определенного интервала по формуле трапеций.
В основной программе использовать процедуру TRAP для вычисления интегралов:
∫ (х 2 + cos(x)) dx и ∫ (tg(x+1))/(x+1) dx
от –1 до 4 от 0 до 2
Задача 10.Составить подпрограмму-процедуру NEIBR отыскивания ближайшей из 10 точек, заданных массивом их декартовых координат, кривой F(x) при одной координате x.
В основной программе использовать процедуру NEIBR для функций cos(x) и sin(x).
Задача 11.Составить подпрограмму-процедуру MASSHTAB отыскивания масштаба графического изображения функции f(x) на экране размером В единиц растра по формуле M=B/max f(x).
В основной программе использовать процедуру для отыскания масштаба функций z2sin(x) и tg(x), при х<1.
Задача 12.Составить подпрограмму - процедуру RT для отыскания наименьшего положительного корня уравнения F(x)=0 c точностью e=0.00001 методом итераций.
В основном программе использовать процедуру для решения уравнения x - tg(x) = 0 , используя обратную функцию x1 = arcing(x0) + k p.
Задача 13. Составить подпрограмму-процедуру ВR для отыскания ближайшей из 10 точек, заданных массивом их декартовых координат, к кривой F(x) при одной и той же координате х.
В основном программе использовать процедуру ВR для функций cos(x) и sin(x).
Задача 14. Составить подпрограмму-процедуру MAXIM для отыскания максимального расстояния между двумя кривыми F(x) и G(x) при одной и той же абсциссе х на интервале от xmin до xmax.
В основном программе использовать процедуру MAXIM для функций sin(x)/x и tg(x+1)/(x+1) в интервале 0,5…1 с шагом 0,02.
Задача 15. Составить подпрограмму-процедуру ROOT отыскания минимального положительного корня уравнения f(x)=0 с точностью e=0.0001 методом деления пополам отрезка, содержащего корень.
В основном программе использовать процедуру для решения уравнений x2 + sin(x/2)= 0 и arctg(x) + x = 1.
Задача 16. Cоставить подпрограмму-функцию INTG для вычисления определенного интервала по формуле прямоугольников.
В основной программе использовать процедуру INTG для вычисления интегралов:
∫ (cos(х)/(x) dx и ∫ (ctg(x+1))/(x+1) dx
от –0,1 до 4 от 0 до 2
Задача 17. Cоставить подпрограмму-функцию INTGR для вычисления определенного интервала по формуле прямоугольников.
В основной программе использовать процедуру INTGR для вычисления интегралов:
∫ ex/(x+1) dx и ∫ (sgrt(x-1)) dx
от –0 до 1 от 0 до 2
Задача 18. Cоставить подпрограмму-функцию INTEG для вычисления определенного интервала по формуле трапеций.
В основной программе использовать процедуру INTEG для вычисления интегралов:
∫ sin(х)/(x) dx и ∫ (tg(x+1))/(x+1) dx
от –0,1 до 1 от 0 до 2
Задача 19. Cоставить подпрограмму-функцию INT для вычисления определенного интервала по формуле прямоугольников.
В основной программе использовать процедуру INT для вычисления интегралов:
∫ sin(х)/(x) dx и ∫ (tg(x+1))/(x+1) dx
от –0,1 до 1 от 0.1 до 2
Задача 20. Cоставить подпрограмму-функцию INTGR для вычисления определенного интервала по формуле прямоугольников.
В основной программе использовать процедуру INTGR для вычисления интегралов:
∫ ex /(x+1) dx и ∫ sgrt(x-1) dx
от –0 до 1 от 0 до 2
Задача 21. Cоставить подпрограмму-функцию TRAP для вычисления определенного интервала по формуле трапеций.
В основной программе использовать процедуру TRAP для вычисления интегралов:
∫ (х2 + cos(x)) dx и ∫ (tg(x+1))/(x+1) dx
от –1 до 4 от 0 до 2
Задача 22. Разработать подпрограмму, которая определяет корни уравнения y = x2 – 2 на заданном отрезке методом половинного деления.
Задача 23. Cоставить подпрограмму-функцию Integr для вычисления определенного интервала по формуле прямоугольников.
В основной программе использовать процедуру INTGR для вычисления интегралов:
∫ ex /(x+1) dx и ∫ sgrt(x-1) dx
от –0 до 1 от 0 до 2
Задача 24. Составить подпрограмму-процедуру Сoren отыскания всех корней уравнения f(x)=0 с точностью e=0.0001 методом Ньютана-Рафсона.
Лекция "3.3. Модели составных узловых элементов сети" также может быть Вам полезна.
В основном программе использовать процедуру для решения уравнения x3 – 1,473x2 - 5,738х + 6,763 = 0.
Задача 25. Составить подпрограмму-процедуру Сrn отыскания всех корней уравнения f(x)=0 с точностью e=0.1; 0.01; 0,001; 0,0001 методом деления отрезка пополам.
В основном программе использовать процедуру для решения уравнения ch(x) + cos(x) – 3 = 0.