case..of с функцией - PullRequest
       4

case..of с функцией

1 голос
/ 09 февраля 2011

это моя программа ... мне нужна помощь, как я могу использовать функцию CalkaNadmiar для 2: в (случай rgMetoda.ItemIndex of) и функцию CalkaNiedomiar для 3:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  fx= function(x:extended):extended;
  TForm1 = class(TForm)
    Naglowek: TLabel;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    edPrzedzialy: TEdit;
    edOd: TEdit;
    edDo: TEdit;
    pnWynik: TPanel;
    Oblicz: TButton;
    rgMetoda: TRadioGroup;
    rb1: TRadioButton;
    rb2: TRadioButton;
    rb3: TRadioButton;

    function f1(X: Extended): Extended;
    function f2(X: Extended): Extended;
    function f3(X: Extended): Extended;
    procedure ObliczClick(Sender: TObject);
    procedure edPrzedzialyExit(Sender: TObject);
    procedure edOdExit(Sender: TObject);
    procedure edDoExit(Sender: TObject);




  private
         function CalkaNadmiar (odx,dox:extended; n:integer; f:fx):extended;
     function CalkaNiedomiar (odx,dox:extended; n:integer; f:fx):extended;
     function Calka (odx,dox:extended; n:integer; f:fx):extended;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.f1(x: Extended): Extended;
begin
 Result:=sqr(x)+ 2;
end;

function TForm1.f2(X: Extended): Extended;
begin
 Result:=3*x - 8;
end;

function TForm1.f3(X: Extended): Extended;
begin
 Result:=sin(x) + Pi;
end;


 procedure TForm1.ObliczClick(Sender: TObject);
var Wynik, h, xi: real;
    i,n: word;
//h - krok całkowania
// Wynik - chwilowy lub końcowy wynik danej funkcji
//xi - x dla kolejnego kroku całkowania
//n - liczba przedziałów
//i - obsluga pętli
begin
 n:=StrToInt(edPrzedzialy.Text);
 h:=(StrToFloat(edDo.Text)-StrToFloat(edOd.Text))/n;
 Wynik:=0;
 case rgMetoda.ItemIndex of
  0: begin //obsługa metody prostok±tów z nadmiarem
   if rb1.Checked then
    begin
     for i:=0 to n-1 do
      begin
       xi:=StrToFloat(edOd.Text)+i*h;
       Wynik:= Wynik + f1(xi)*h;
      end;
     pnWynik.Caption:= FloatToStr(Wynik);
    end;
   if rb2.Checked then
    begin
     for i:=0 to n-1 do
      begin
       xi:=StrToFloat(edOd.Text)+i*h;
       Wynik:= Wynik + f2(xi)*h;
       end;
        pnWynik.Caption:= FloatToStr(Wynik);
      end;
    if rb3.Checked then
      begin
       for i:=0 to n-1 do
        begin
         xi:=StrToFloat(edOd.Text)+i*h;
         Wynik:= Wynik + f3(xi)*h;
      end;
     pnWynik.Caption:=FloatToStr(Wynik);
   end;
   end;


  1: begin //obsługa metody prostok±tów z niedomiarem
   if rb1.Checked then
    begin
     for i:=1 to n do
      begin
       xi:= StrToFloat(edOd.Text) + i*h;
       Wynik:= Wynik + f1(xi)*h;
      end;
     pnWynik.Caption := FloatToStr(Wynik);
    end;
   if rb2.Checked then
    begin
     for i:=1 to n do
      begin
       xi:=StrToFloat(edOd.Text) + i*h;
       Wynik:= Wynik + f2(xi)*h;
      end;
     pnWynik.Caption:=FloatToStr(Wynik);
    end;
         if rb3.Checked then
      begin
       for i:=0 to n-1 do
        begin
         xi:=StrToFloat(edOd.Text)+i*h;
         Wynik:= Wynik + f3(xi)*h;
      end;
     pnWynik.Caption:=FloatToStr(Wynik);
  end;
end;
end;
end;


procedure TForm1.edPrzedzialyExit(Sender: TObject);
begin
 if (StrToFloat(edPrzedzialy.Text)<10000) or
    (StrToFloat(edPrzedzialy.Text)>100000000)
 then
  begin
   showmessage('Podaj liczbę z przedziału [10000 - 100000000].');
   edPrzedzialy.SetFocus;
  end;
 if Frac(StrToFloat(edPrzedzialy.Text))<>0 then
{sprawdzamy czy została wprowadzona liczba całkowita}
  begin
   showmessage('Podaj liczbę całkowitą.');
   edPrzedzialy.SetFocus;
  end;
end;

procedure TForm1.edOdExit(Sender: TObject);
begin
 if StrToFloat(edOd.Text)>=StrToFloat(edDo.Text) then
  begin
   showmessage('Podaj liczbę mniejsz± niż górna granica całkowania.');
   edOd.SetFocus;
  end;
end;

procedure TForm1.edDoExit(Sender: TObject);
begin
if StrToFloat(edDo.Text)<=StrToFloat(edOd.Text) then
  begin
   showmessage('Podaj liczbę większą niż dolna granica całkowania.');
   edDo.SetFocus;
  end;
  end;

  function TForm1.CalkaNadmiar (odx,dox:extended; n:integer; f:fx):extended; //trapez z nadmiarem
var i:integer;  xi,h,Wynik:extended;
begin
    Wynik:=0;
    h:=(Dox-Odx)/n;
for i:= 0 to n-1 do
    begin
        Wynik:=f(xi)*h+Wynik;
        xi:=xi+h;
    end;
    Result:=Wynik;
 end;

    function TForm1.CalkaNiedomiar (odx,dox:extended; n:integer; f:fx):extended; //trapez z niedomiarem
var i:integer;  xi,h,Wynik:extended;
begin
    Wynik:=0;
    h:=(Dox-Odx)/n;
for i:= 1 to n do
    begin
        Wynik:=f(xi)*h+Wynik;
        xi:=xi+h;
    end;
    Result:=Wynik;
end;

 function TForm1.Calka (odx,dox:extended; n:integer; f:fx):extended;  //trapez
 var i:integer;  xi,h,Wynik:extended;
begin
    Wynik:=0;
    h:=(Dox-Odx)/n;
for i:= 1 to n-1 do
    begin
        Wynik:=f(xi)+Wynik;
        xi:=xi+h;
    end;
    Wynik:=(f(odx) + f(dox) + Wynik)*h/2;
    Result:=Wynik;
end;


end.

Ответы [ 2 ]

3 голосов
/ 09 февраля 2011

Я думаю, что это будет полезно для вас

case ( rgMetoda.ItemIndex ) of
  2 : begin CalkaNadmiar;    end;

  3 : begin CalkaNiedomiar; end;   

  else begin               
    //Call other function
  end;
end; 
1 голос
/ 09 февраля 2011

Ваше определение типа процедурного типа TFx несовместимо с методами объекта, включая TForm .

  type
    TFx = function(a: extended): extended;
    TMx = function(a: extended): extended of object;

TFx совместимо с функциями первого класса, то есть функциями, объявленными на уровне модуля, а не как члены / методы класса.

TMx совместим с методами-членами (то есть, что означает " объекта " в объявлении.

A TFx и TMx не являются совместимыми типами, поскольку в то время как TFx является указателем на функцию, TMx является на самом деле TWO указатели: указатель на метод класса AND указатель на конкретный экземпляр этого класса.

С этой информацией, я думаю, вы сможете увидеть, что то, что вам может понадобиться, выглядит примерно так (для краткости только существенные отличия от вашего кода показаны):

  type
    TFx = function(x: extended): extended of object;


  procedure TForm1.ObliczClick(Sender: TObject);
  var
    Wynik, h, xi: real;
    i,n: word;
    fn: TFx;
  begin
    n:=StrToInt(edPrzedzialy.Text);
    h:=(StrToFloat(edDo.Text)-StrToFloat(edOd.Text))/n;
    Wynik:=0;

    if rb1.Checked then fn := f1
    else if rb2.Checked then fn := f2
    else if rb3.Checked then fn := f3;

    for i:=0 to n-1 do
    begin
      xi:=StrToFloat(edOd.Text)+i*h;
      Wynik:= Wynik + fn(xi)*h;
    end;
    pnWynik.Caption:= FloatToStr(Wynik);

    ..
  end;

В качестве альтернативы, поскольку ваши f1 , f2 и f3 на самом деле не обязательно должны быть методами-членами TForm (они делают не использовать никакие данные экземпляра) вы можете оставить объявление TFx как есть и просто переместить f1 , f2 и f3 за пределы класса и просто объявите их как функции первого класса в разделе реализации модуля:

Также обратите внимание, что в любом случае сам тип TFx также не требуется вне раздела реализации (в зависимости от опубликованного кода, хотя в более широком контексте это может быть не так) :

осуществление

  type
    TFx = function(x: extended): extended of object;


  function f1(x: Extended): Extended;
  begin
    result:=sqr(x)+ 2;
  end;


  function f2(X: Extended): Extended;
  begin
    result:=3*x - 8;
  end;


  function f3(X: Extended): Extended;
  begin
    result:=sin(x) + Pi;
  end;



  procedure TForm1.ObliczClick(Sender: TObject);
  var
    Wynik, h, xi: real;
    i,n: word;
    fn: TFx;
  begin
    n:=StrToInt(edPrzedzialy.Text);
    h:=(StrToFloat(edDo.Text)-StrToFloat(edOd.Text))/n;
    Wynik:=0;

    if rb1.Checked then fn := f1
    else if rb2.Checked then fn := f2
    else if rb3.Checked then fn := f3;

    for i:=0 to n-1 do
    begin
      xi:=StrToFloat(edOd.Text)+i*h;
      Wynik:= Wynik + fn(xi)*h;
    end;
    pnWynik.Caption:= FloatToStr(Wynik);

    ..
  end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...