case..of 与函数

发布于 2024-10-16 18:16:13 字数 5088 浏览 2 评论 0原文

这是我的程序...我需要帮助如何使用函数 CalkaNadmiar for 2: in (case rgMetoda.ItemIndex of) 和函数 CalkaNiedomiar for 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.

this is my program... i need help how i can use function CalkaNadmiar for 2: in (case rgMetoda.ItemIndex of) and function CalkaNiedomiar for 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

听风念你 2024-10-23 18:16:13

我想这会对你有帮助

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

  3 : begin CalkaNiedomiar; end;   

  else begin               
    //Call other function
  end;
end; 

I think this will be helpful to you

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

  3 : begin CalkaNiedomiar; end;   

  else begin               
    //Call other function
  end;
end; 
歌枕肩 2024-10-23 18:16:13

您的过程类型 TFx 的类型定义与对象(包括 TForm)的方法不兼容。

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

TFx 与第一类函数兼容,即在单元级别声明的函数,而不是作为类的成员/方法声明的函数。

TMx 与成员方法兼容(这就是声明中“对象”的含义。

TFxTMx< /strong> 不是兼容类型,因为虽然 TFx 是指向函数的指针,但 TMx 实际上是两个指针:指向函数的指针类方法指向该类的特定实例的指针

有了这些信息,我认为您应该能够看到您可能会遇到类似的情况(仅与显示的代码有显着差异,为简洁起见):

  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;

或者,因为您的 f1f2f3 函数实际上不需要是 TForm 的成员方法strong>(它们不使用任何实例数据)您可以保留 TFx 声明不变,只需移动 f1f2f3 在类之外,只需在单元实现部分将它们声明为第一类函数:

另请注意,在任何一种情况下,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;

Your type definition of the procedural type TFx is incompatible with the methods of an object, including a TForm.

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

TFx is compatible with first class functions, that is functions declared at the unit level, not as members/methods of a class.

TMx is compatible with member methods (that is what the "of object" means in the declaration.

A TFx and a TMx are not compatible types because whilst a TFx is a pointer to a function, a TMx is actually TWO pointers: a pointer to an class method AND a pointer to a specific instance of that class.

With that information, I think you should be able to see that what you might be after is something like (only significant differences from your code shown, for brevity):

  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;

Alternatively, since your f1, f2 and f3 functions do not actually need to be member methods of TForm (they make no use of any instance data) you could leave the TFx declaration as it is and simply move the f1, f2 and f3 outside of the class and simply declare them as first class functions in the unit implementation section:

Note also that in either case, the TFx type itself is not needed outside of the implementation section either (based on the code you have posted, tho in the broader context this may not be the case):

implementation

  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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文