Семестр2_Семинар7


Чтобы посмотреть этот PDF файл с форматированием и разметкой, скачайте файл и откройте на своем компьютере.
2 - й семестр Семинар 7 : Процедурные типы. Приближенные вычисления. Процедурные типы . Основное назначение - предоставить программисту гибкие средства передачи процедур и функций в качестве фактических параметров при обращени и к другим процедурам и функци ям. С уществует два процедурных типа: тип - процедура и тип - функция . Для о бъявлени я процедурного типа используется заголовок процедуры (функции), в котором опускается ее имя, например: type TProc = procedure (X, Y: Integer); TFunc = function (X, Y: Int eger): Boolean; Определив процедурный тип, можно непосредственно перейти к так называемым процедурным переменным . Они объявляются точно так же, как и обычные переменные. var P 1 : TProc; F 1, F2 : TFunc; P2 : array [1..N] of TProc ; При работе с процеду рной переменной важно понимать, что она не дублирует код подпрограммы, а содержит лишь ее адрес . Если обратиться к такой переменной как к подпрограмме, произойдет выполнение подпрограммы, адрес которой записан в переменной. Пример: Варианты вызова, присвое ния type TFunc = Function (i : Integer) : Integer; Function MyFunc (count : Integer) : Integer; // far; begin ....... end; { MyFunc } var VarFunc1, VarFunc2 : TFunc; i : Integer ; begin {Основная программа} ....... i := MyFunc(1) ; {Обычное использование результата функции. Вызов функции } ....... VarFunc1 := MyFunc; { Вызова функции нет. } { Присваивание переменной процедурного типа имени функции MyFunc } ....... VarFunc 1 := MyFunc (1); { Error ! Недопустим о, так как слева и справа от знака присваивания используются несовместимые типы: слева - процедурный тип, а справа - INTEGER; } ....... VarFunc 2 := VarFunc 1; {вызова функции нет} ....... I := VarFunc 2(123); { вызов функции } ....... end . Таки м образом : И мя функции со списком фактических параметров MyFunc(1) трактуется как вызов функции, в то время как имя функции без списка параметров рассматривается как адрес функции. Обращение к процедурной переменной следует выполнять только после установ ки ее значения. После такого присваивания имя переменной становит ся синонимом имени подпрограммы. Когда переменная процедурного типа указывается в левой части оператора присваивания, в правой части ожидается значение процедурного типа, т.е. имя подпрограмм ы либо другая процедурная переменная. Во всех других контекстах предполагается вызов подпрограммы, с которой связана процедурная переменная Два процедурных типа являются совместимыми , если они имеют: одинаковый формат вызова (the same calling convention), т.е. оба являются процедурами или функциями; одинаковый тип возвращаемого значения либо не имеют его вовсе; одинаковое число, тип и порядок следования параметров. Имена параметров значения не имеют. Пример 1 : Приближенное вычисление интеграла ( два способа ) и корня. Модуль пользователя (дополнительный). unit Unit2; interface type TFunc = function( x : real) : real; function Integral1 ( Func : TFunc; a, b, h : real) : real; function Integral2 ( Func : TFunc; a, b, h : real; var n:integer) : real; Functi on Root (Func : TFunc; a,b,h : real) : real; I mplementation // ------------------------------------------------------------------- // Приближенное вычисление интеграла функции Func на отрезке от a до b с шагом h function Integral1 ( Func : TFunc; a, b, h : real) : real; var c, x, y : real; begin Result := 0; c := a; while c b do begin if c + h b then x := c + h/2 else begin h := b - c; x := (c+b)/2; end; y := Func(x); Result := Result + h*y; c := c + h; end; end ; // ------------------------------------------------------------------- // Приближенное вычисление интеграла функции Func на отрезке от a до b с точностью h function Integral2 ( Func : TFunc; a, b, h : real; var n:integer) : real; var i : integ er; xx, dx, s1 : real; begin n:=10; Result := 0; repeat s1 := Result; Result := 0; dx := (b - a)/n; xx := a; for i:=1 to n do begin Result := Result + Func(xx)*dx; xx := xx+dx; end; n := n*2; until abs(Result - s1)h; end ; // ------------------------------------------------------------------- // Нахождение корня функции Func на отрезке от a до b с точностью h Function Root ( Func : TFunc; a,b,h : real ) : real; var c : real; begin repeat c := (a+b)/2; if Func(a)*Func(c) = 0 then b:=c else a:=c; until ( (b - a)/2 h ) or (Func(c) = 0); result := c; end ; // ------------------------------------------------------------------- end . Основной модуль с интерфейсом unit Unit1; interface uses Window s, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Unit2 ; type TForm1 = class(TForm) Label1: TLabel; Label2: TLabel; Label3: TLabel; AEdit: TEdit; BEdit: TEdit; HEdit: TEdit; M emo1: TMemo; SelectRadioGroup: TRadioGroup; CosRadioButton: TRadioButton; SinRadioButton: TRadioButton; RunButton: TButton; procedure RunButtonClick(Sender: TObject); private { Private declarations } public { Public declarat ions } end; var Form1: TForm1; Func : TFunc; implementation {$R *.dfm} // ------------------------------------------------------------------- Function f1 (x:real):real; begin f1:=sin(x); end ; // ------------------------------------------------- ------------------ Function f2 (x:real):real; begin f2:=Cos(x); end ; // ------------------------------------------------------------------- // Реакция на нажатие кнопки RunButton procedure TForm1. RunButtonClick (Sender: TObject); var OpIndex, FuncIndex , Code1, Code2, Code3, n : integer; s1, s2, s3 : string; a, b, h, c, x, y, Result : real; begin if( CosRadioButton.Checked ) then Func := f2; if( SinRadioButton.Checked ) then Func := f1; s1 := AEdit.Text; Val( s1, a, Code1 ); s2 := BEdit.Text ; Val( s2, b, Code2 ); s3 := HEdit.Text; Val( s3, h, Code3 ); ���if( Code10 ) or ( Code20 ) or ( Code30 ) then begin ShowMessage('Error!'); exit; end; OpIndex := SelectRadioGroup.ItemIndex; case OpIndex of 0: begin Memo1. Lines.Add( 'Integral1 ' + FloatToStr( Integral1 (Func,a,b,h) )); end; 1: begin n := 0; Memo1.Lines.Add( 'Integral2 ' + FloatToStr( Integral2 (Func,a,b,h,n) )); end; 2: begin Memo1.Lines.Add( 'Root ' + FloatToStr( Root (Func,a,b,h) )); end; end; end ; // ------------------------------------------------------------------- end.

Приложенные файлы

  • pdf 26590881
    Размер файла: 328 kB Загрузок: 0

Добавить комментарий