Лекция: Процедурні типи

Для організації передачі процедур і функцій як параметрів при зверненні до інших процедур і функцій введено процедурний тип. Існує два процедурних типи: тип-процедура і тип-функція. Для опису процедурного типу використовується заголовок процедури або функції, в якому опускається ім’я, наприклад:

 

TYPE Tproc = Procedure (a, b, c: double; var v, w: double );

TFun = Function ( x, y: double): double;

Function Sum( x, y: double): double; far;

Begin

Result:=x+y;

End;

VAR P: Tproc;

F: Tfun;

a, b, c, d, z: double;

BEGIN

writeln (‘Введіть a, b, c, d’);

readln (a, b, c, d);

F:=Sum;

z:=Sum(a, b) – F(c, d);

writeln (‘z=’,z);

END.

Із прикладу видно, що процедурній змінній P можна присвоювати як значення ім’я процедури, а змінній F ім’я функції. Після присвоєння ім’я змінної стає синонімом імені підпрограми і його можна використовувати для звернення до підпрограми.

Процедура або функція, яка присвоюється процедурній змінній, повинна транслюватися з дальнім переходом (з директивою FAR). Крім цього вона не може бути стандартною процедурою або функцією і не може бути локальною, тобто вкладеною.

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

Приклад 1. Розробити програму обчислення значень інтеграла

,

методами трапецій та Сімпсона з точністю для, що змінюється на інтервалі з кроком. Результат вивести у вигляді таблиці у кожному рядку параметр та значення інтегралу.

Для розв’язку задачі командою File|New Application створимо новий проект. Присвоїмо формі заголовок Обчислення інтегралів (властивість Caption). Командою File|Save All запишемо програмний модуль у файл з іменем ULAB9_1.pas, а проект – PLAB9_1.dpr.

Розробимо форму для введення початкових даних і виведення результату Рис.9.1.

Розмістимо на цій формі шість компонентів Edit для введення початкових даних: меж інтегрування – a, b; точності обчислення інтеграла – e; меж і кроку зміни параметра t –. Для вибору методу використаємо компонент ComboBox. Встановимо йому початкове значення властивості Text=Трапецій, а увесь список методів: Трапецій, Сімпсона присвоїмо властивості Items

Для виведення результатів використаємо компонент StringGrid і втановимо йому такі значення властивостей: ColCount=2, ColCount=20, FixedCols=o, FixedRows=20.

Пояснення до цих компонентів зробимо за допомогою компонента Label (властивість Caption).

Крім цього, розмістимо на формі дві керуючі кнопки (компонент Button) з написами Обчислити та Вихід.

 

 

Рис 9.1. Форма Обчислення інтегралів

 

Функції для обчислення інтегралів методами трапецій та Сімпсона розмістимо в окремому програмному модулі іменем UINTEG.

Для створення модуля, не пов’язаного з формою, потрібно виконати команду File|New і у вікні діалогу вибрати значок з підписом Unit, на екрані з’явиться заготовка модуля в яку слід томістити текст і запам’ятати під іменем UINTEG.

 

Модуль UINTEG має вигляд:

unit UINTEG;

interface

 

{ Процедурний тип }

TYPE TFun = Function ( x: real; t:integer): real;

Type Tfunr=function(x:real):real;

{ Заголовки функцій }

Function Mtrap(a, b, e: real; t:integer; F: TFun): real;

Function Msimp(a, b, e: real; t:integer; F: TFun):real;

Function Mpodil(a,b,e:real; f:Tfunr):real;

 

implementation

 

{ Метод трапецій }

Function Mtrap(a, b, e: real; t:integer; F: TFun): real;

Const n=10;

Var x, h, d, s2, s2n: real;

i, m: integer;

begin

m:=n;

repeat

h:=(b-a)/m;

s2n:=(F(a, t)+F(b, t))/2;

for i:=1 to m-1 do

begin

x:=a+i*h;

s2n:= s2n+F(x, t);

end;

s2n:= s2n*h;

if m=n then d:=e+1 else d:=abs(s2n-s2);

s2:=s2n; m:=m*2;

until d<e;

result:=s2n;

end;

 

{ Метод Сімпсона }

Function Msimp(a, b, e: real; t:integer; F: TFun): real;

Const n=10;

Var x, h, d, s2, s2n,R1,R2: real;

i, m: integer;

begin

m:=n;

repeat

h:=(b-a)/(2*m);

R1:=0; R2:=0;

s2n:=(F(a, t)+F(b, t));

for i:=1 to m do

begin

x:=a+(2*i-1)*h;

R1:= R1+F(x, t);

end;

for i:=1 to m-1 do

begin

x:=a+2*i*h;

R2:= R2+F(x, t);

end;

s2n:= (s2n+4*R1+2*R2)*h/3;

if m=n then d:=e+1 else d:=abs(s2n-s2);

s2:=s2n; m:=m*2;

until d<e;

result:=s2n;

end;

{ Метод поділу відрізка навпіл }

function Mpodil(a,b,e:real; f:Tfunr):real;

var x:real;

begin

x:=(a+b)/2;

while abs(b-a)>e do

begin

x:=(a+b)/2;

if f(x)=0 then break;

if f(a)*f(x)<=0 then b:=x;

if f(a)*f(x)>0 then a:=x;

end;

result:=x;

end;

end.

Після компіляції модуля UINTEG його слід командою File|Use Unit підключити до проекту.

Обробник кнопки Обчислити та підінтегральна функція розміщені у програмному модулі ULAB9_1.

 

Unit ULAB9_1;

................ .

implementation

 

uses UINTEG;

 

{$R *.DFM}

{Підінтегральна функція}

Function F1(x: real; t:integer): real;far;

var i:integer;

begin

Result:=1;

for i:=1 to t do

Result:=Result*x;

end;

 

{Обробник кнопки Обчислити}

procedure TForm1.Button1Click(Sender: TObject);

VAR a, b, e: real;

i, t, t1, t2, h:integer;

i1: real;

BEGIN

{Введення початкових даних}

a:=StrToFloat(Edit1.Text);

b:=StrToFloat(Edit2.Text);

e:=StrToFloat(Edit3.Text);

t1:=StrToInt(Edit4.Text);

t2:=StrToInt(Edit5.Text);

h:=StrToInt(Edit6.Text);

{Виведення результату}

StringGrid1.Cells[0,0]:='Трапецій';

StringGrid1.Cells[1,0]:='Сімпсона';

t:=t1;i:=1;

while (t<=t2) do

begin

if ComboBox1.Text='Трапецій' then i1:=Mtrap(a, b, e, t, F1);

if ComboBox1.Text='Сімпсона' then i1:=Msimp(a, b, e, t, F1);

StringGrid1.Cells[0,i]:=FloatToStr(t);

StringGrid1.Cells[1,i]:=FloatToStr(i1);

t:=t+h;

i:=i+1;

end;

end;

end.

 

Приклад 2.Розробити програму уточнення коренів рівняння на відрізку з різною точністю, методом поділу відрізка навпіл:

, .

Результат вивести у вигляді таблиці.

Для розв’язку задачі командою File|New Application створимо новий проект. Присвоїмо формі заголовок Обчислення інтегралів (властивість Caption). Командою File|Save All запишемо програмний модуль у файл з іменем ULAB9_2.pas, а проект – PLAB9_2.dpr.

Розробимо форму для введення початкових даних і виведення результату Рис.9.2.

Розмістимо на цій формі три компоненти Edit для введення меж проміжку і точності обчислення.

Для виведення результатів використаємо компонент StringGrid і втановимо йому такі значення властивостей: ColCount=2, ColCount=20, FixedCols=0, FixedRows=20.

Пояснення до цих компонентів зробимо за допомогою компонента Label (властивість Caption).

Крім цього, розмістимо на формі дві керуючі кнопки (компонент Button) з написами Обчислити та Вихід

Функцію для обчислення кореня рівняння методом поділу відрізка навпіл розмістимо в окремому програмному модулі UINTEG (див. Приклад 1).

Обробник кнопки Обчислити та функція розміщені у програмному модулі ULAB9_2.

 

Unit ULAB9_2;

............... .

implementation

 

uses UINTEG;

 

{$R *.DFM}

 

{Функція }

function fk(x:real):real;FAR;

begin

result:=sqr(sqr(x))*x-x-0.2;

end;

{Обробник кнопки Обчислити}

procedure TForm1.Button1Click(Sender: TObject);

var a,b,e:real;

n,i:integer;

begin

a:=StrToFloat(Edit1.Text);

b:=StrToFloat(Edit2.Text);

n:=StrToInt(Edit3.Text);

{Виведення результату}

StringGrid1.Cells[0,0]:='Точність';

StringGrid1.Cells[1,0]:='Корінь';

if fk(a)*fk(b)>0 then

ShowMessage('Кореня немає')

else

begin

e:=1;

for i:=1 to n do

begin

e:=e*0.1;

StringGrid1.Cells[0,i]:=FloatToStr(e);

StringGrid1.Cells[1,i]:=FloatToStr(Mpodil(a,b,e,fk));

end;

end;

end;

еще рефераты
Еще работы по информатике