Лекция № 16 Процедуры и функции как параметры Назначение процедур и функций 1. Возможность разбивки программы на блоки. 2. Независимая разработка блоков программы. 3. Составление программы из готовых блоков. 4. Легкая перестановка блоков программы. 5. Устранение дублей. 6. Разделение труда разработчиков. 7. Создание библиотек программ. Пример 1. Процедура печатающая таблицу значений функции. Дана функция f(x) = sin(2*x). Вывести значения функции в N точках от x0 до xn. Пример x0 xn dx dx = (xn-x0)/(N-1) for k:=1 to N do begin xt := (k-1)*dx + x0; yt := f(xt); end; Пример без процедуры var k:integer; xt,yt,x0,xn,dx:real; N:integer; function f(x:real):real; begin f:=sin(2*x); end; BEGIN N:=10; x0:=0.0; xn:=2*pi; dx:=(xn-x0)/(N-1); for k:=1 to N do begin xt:=(k-1)*dx+x0; yt:=f(xt); writeln('x = ',xt:0:2,' f(x) = ',yt:0:2); end; END. Пример с процедурой function f(x:real):real; begin f:=sin(2*x); end; procedure TableFX(x0,xn:real; N:integer); var k:integer; xt,yt,dx:real; begin dx:=(xn-x0)/(N-1); for k:=1 to N do begin xt:=(k-1)*dx+x0; yt:=f(xt); writeln('x = ',xt:0:2,' f(x) = ',yt:0:2); end; end; BEGIN TableFX(0.0, 2*pi, 10); END. Если добавятся функции s(x), g(x), p(x) ? Можно создать еще три процедуры TableSX, TableGX, TablePX. В этом случае получим дублирование кода, что нерационально. Идея – передавать в процедуру формальную функцию. Параметры - функции Создаём новый тип – функция, которая возвращает real и принимает real значения. type func = function(x:real):real; function f(x:real):real; FAR; ... procedure Table(x0,xn:real; N:integer; ft:func); ... xt:=(k-1)*dx+x0; yt:=ft(xt); ... BEGIN Table(0.0, 2*pi, 10, @f); END. Окончательная программа type func = function(x:real):real; {процедурный тип} function f(x:real):real; FAR; begin f:=sin(2*x); end; procedure Table(x0,xn:real; N:integer; ft:func); var k:integer; xt,yt,dx:real; begin dx:=(xn-x0)/(N-1); for k:=1 to N do begin xt:=(k-1)*dx+x0; yt:=ft(xt); {табуляция} writeln('x = ',xt:0:2,' f(x) = ',yt:0:2); end; end; BEGIN Table(0.0, 2*pi, 10, @f); END. Вычисление интеграла методом Монте-Карло 1 f x dx 0 f x1 x 0;1 0 1 0 P f x dx N P – число черных точек N – всего точек 1 cos 2 x dx x 2 0 1 type func = function(x:real):real; function f(x:real):real; FAR; begin f:=x+cos(2*x)-0.5; end; function INTEG(a,b:real; ft:func):real; var k,P,N:integer; xt,yt:real; begin P:=0; N:=30000; for k:=1 to N do begin xt:=random; yt:=random; if (yt<ft(xt)) then P:=P+1; end; INTEG:=1.0*P/N; end; BEGIN writeln('Integral = ',INTEG(0.0,1.0,@f)); END. Параметры - процедуры const N=10; type vector = array[1..N] of integer; type proc = procedure(var A:vector); var S:vector; procedure Zero(var B:vector); FAR; {--- Обнуление массива} var k:integer; begin for k:=1 to N do B[k]:=0; end; procedure Rand(var B:vector); FAR; {--- Случайный массив} var k:integer; begin for k:=1 to N do B[k]:=random(10); end; Параметры - процедуры procedure PrintVector(var A:vector; PR:proc); {--- Печать массива} var k:integer; begin PR(A); for k:=1 to N do write(A[k]:4); writeln; end; BEGIN PrintVector(S,@Rand); END. PrintVector печатает массивы разного содержания Преимущества Универсализация процедур. Сокращение дублирования кода. Сокращение имен процедур. Одна процедура на множество функций. Массивы функций (процедур) type func=function(x:real):real; procedure Table(x0,xn:real; N:integer; ff:array of func; M:integer); {ff - массив формальных функций, M - количество функций} var k,i:integer; xt,yt,dx:real; begin dx:=(xn-x0)/(N-1); for i:=0 to M-1 do {цикл по всем функциям} begin for k:=1 to N do begin xt:=(k-1)*dx+x0; yt:=ff[i](xt); writeln('x = ',xt:0:2,' f(x) = ',yt:0:2); end; writeln; end; end; Массивы функций (процедур) function f(x:real):real; begin f:=sin(x); end; FAR; function s(x:real):real; begin s:=cos(x); end; FAR; var fff:array[1..2] of func; BEGIN fff[1]:=@f; fff[2]:=@s; Table(0.0, 2*pi, 10, fff,2); END.