User Tools

Site Tools


tutorial:proceduraltype

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
tutorial:proceduraltype [2018/09/09 09:30]
admin [ข้อแตกต่างระหว่าง Lazaus กับ Delphi]
tutorial:proceduraltype [2018/10/28 12:32] (current)
admin
Line 1: Line 1:
 =====Procedural Type===== =====Procedural Type=====
  
-====Procedural Type คืออะไร==== +=====Procedural Type คืออะไร===== 
-คือ การสร้างตัวแปรชนิดที่เป็น procedure/​function เพื่อให้สามารถนำไปใส่ใน input Argument ของ procedure/​function อันอื่นได้ หรือเรียกอีกอย่างหนึ่งคือ การทำให้ procedure/​function กลายเป็นตั่วแปร+คือ การสร้างตัวแปรชนิดที่เป็น procedure/​function เพื่อให้สามารถนำไปใส่ใน input Argument ของ procedure/​function อันอื่นได้ หรือเรียกอีกอย่างหนึ่งคือ การทำให้ procedure/​function กลายเป็นตัวแปร 
 +\\ \\ 
 +=====รูปแบบ===== 
 +Procedural Type มีรูปแบบดังนี้ 
 +^  Topic  ^  Format ​ ^  
 +|Type Declaration|<​sxh delphi;>​ 
 +TYPE 
 +  TFunc1 = function(x:​integer):​real;​ //for function 1-argument 
 +  TFunc2 = function(x,​y:​integer):​real;​ //for function 2-arguments 
 +   
 +  TProc = procedure; //for procedure with no argument 
 +  TProc1 = procedure(y:​string);​ //for procedure 1-argument 
 +</​sxh>​ | 
 + 
 + 
 +<hidden Example-1: Function Finding Max Value> 
 +**ตัวอยาง** การส่ง function เข้าไปอีก function หนึ่ง \\ 
 +__ข้อสังเกต__:​ การหาค่าสูงสุดของ function โดยการสร้าง function ที่มีชื่อว่า Find_Max จะสังเกตว่าภายใน function ดังกล่าว มีการเรียก function จากภายนอกเข้ามาคำนวณ ซึ่งเรียกว่า f() ดังนั้นเราจึงต้องกำหนดให้ f() เป็นตัวแปรชนิด Procedural Type\\ 
 +สำหรับ Lazarus การเรียก func เข้ามาใน Find_Max ในบรรทัดที่ 30 จะเป็นการเรียกผ่าน Pointer ดังนั้นจึงต้องใส่ @ นำหน้าชื่อ function เสมอ
  
 +{{ :​introduction:​plot_polynomial.png?​400 |}}
 + 
 +<sxh delphi;​highlight:​ [4,​13,​30]>​
 +PROGRAM Find_MaxValue_Of_Function;​
  
-<hidden Example-1: ปัญหาการส่งผ่านตัวแปรชนิด function เข้าไปในอีก function หนึ่ง ไม่สามารถทำได้ทันที ดังตัวอย่าง > +TYPE 
-<sxh delphi;>+  Tfunc = function(x:​real):​real//​Procedural Type
  
 //define polynomial function f(x) = x^2+2*x-5 //define polynomial function f(x) = x^2+2*x-5
 +//This function has the Max value = 15 at x = 5
 function func(x:​real):​real;​ function func(x:​real):​real;​
 begin begin
-  result:​=x*x+2*x-;+  result:=-x*x+10*x-10  
 end; end;
  
-//​create ​function ​to find the average value between a and b of any function +function ​Find_Max(f:Tfunc; xFirst,xLast,​increment:real):real; 
-function average_value(a,b:​real):​real;​+var x,xMax,max:real;
 begin begin
-  ​result:=(a+b)/2;+  ​x:=xFirst; 
 +  xMax:=x; 
 +  max:= f(x); 
 +  while x<xLast do 
 +   ​begin 
 +     x:=x+increment;​ 
 +     if f(x)>max then xMax := x; 
 +     max:= f(x); 
 +   ​end;​ 
 +  result:​=f(xMax);
 end; end;
-  ​ 
  
 //Call the above function //Call the above function
 BEGIN BEGIN
-  writeln(average_value(func(1),func(10))); //​Error!!! ​ +  writeln('Max value between x = 0 to x = 10 is : ',​Find_Max(@func,0,10,0.001)); 
-  ​//cannot pass "​func"​ as argument. +  ​readln;
 END.  ​ END.  ​
 </​sxh> ​ </​sxh> ​
 </​hidden>​ </​hidden>​
 +\\ 
  
-จาก Example-1 จ็นว่า เราไม่สามารส่งตัวแปรที่เป็น procedure/function เข้าไปน Argument ของ function average_value ได้ จึงจำเป็นต้องมีารประการ ​Type ของ function ก่อน ังตัวอย่างอไปนี้+====ข้อแตต่างระหว่าง Lazaus กับ Delphi ==== 
 + 
 +ข้อสังกต การส่ function เข้าไปสำหรับ lazarus กับ delphi จะแตกต่างกัน โดย Lazarus จะใช้การส่ค่าผ่าน pointer ​ังนัจึงต้องมีเครื่องหมย @ นำหน้าชื่อ function แต่สำหับ delphi สามารถส่ชื่อ ​function เข้าไปไ้เลย ดูตัวอย่างที่ 
 + 
 +<hidden Example-2: Function Finding Max Value (Delphi) > 
 +<sxh delphi;​highlight:​ [3,​32]>​ 
 +PROGRAM Find_MaxValue_Of_Function;​ 
 + 
 +{$MODE delphi}
  
-<hidden Example-2: แก้ปัญหาโดยการประกาศตัวแปร Procedural Type ก่อน > +TYPE 
-<sxh delphi;>​ +  Tfunc = function(x:​real):​real; ​//​Procedural Type
-Type +
-  Tfunc = function(x:​real):​real ​of object+
  
 //define polynomial function f(x) = x^2+2*x-5 //define polynomial function f(x) = x^2+2*x-5
 +//This function has the Max value = 15 at x = 5
 function func(x:​real):​real;​ function func(x:​real):​real;​
 begin begin
-  result:​=x*x+2*x-;+  result:=-x*x+10*x-10  
 end; end;
  
-//​create ​function ​to find the average value between a and b of any function +function ​Find_Max(f:​Tfunc; ​xFirst,xLast,​increment:real):real; 
-function average_value(f:​Tfunc; ​a,b:​real):​real;​+var x,xMax,max:real;
 begin begin
-  ​result:=(f(a)+f(b))/2;+  ​x:​=xFirst;​ 
 +  xMax:=x; 
 +  max:= f(x)
 +  while x<xLast do 
 +   ​begin 
 +     x:=x+increment;​ 
 +     ​if ​f(x)>max then xMax := x; 
 +     max:= f(x); 
 +   ​end;​ 
 +  result:​=f(xMax);
 end; end;
-  ​ 
  
 //Call the above function //Call the above function
 BEGIN BEGIN
-  writeln(average_value(@func,1,10));  +  writeln('Max value between x = 0 to x = 10 is : ',​Find_Max(func,0,10,0.001)); 
- +  ​readln;​ 
-END.  +END.
 </​sxh> ​ </​sxh> ​
 </​hidden>​ </​hidden>​
 +----
  
 +=====Function of Object=====
 +ตัวอย่างข้างบนนั้น ใช้ได้กับกรณีที่ function ถูกประกาศเป็น Global Scope เท่านั้น (จะสังเกตว่า func ไม่ได้อยู่ภายใต้ Class หรือ Object ใดๆ) ในกรณีที่ function ถูกประกาศเป็น Local Scope ภายใต้ Class หรือ Object ใดๆ จะต้องเปลี่ยนการประกาศ Type ใหม่เป็นดังนี้
  
-====ข้อแตกต่างระหว่าง Lazaus กับ Delphi ====+  Type  
 +    TFunc function(x:​real):​real of Object ;
  
-ข้อสังเกต ​การใส่ function เข้าไสำหับ lazarus กับ delphi จแตต่างกัน โดย Lazarus จะ้การส่งค่ผ่าน pointer ดังนั้นึงต้องมีรืองหมย @ นำหน้าชื่อ function แ่สำหรับ delphi สามารถส่งชื่อ ​function เข้าไปได้ลย ดูตัวย่างที่ 3+<hidden Example-3: Function of Object (TForm)>​ 
 +**ตวอย่า** การประกาศ Procedural Type ของ function ที่ประาศภายใ้ Form1\\ 
 +__ข้อสังเกต__: ​การประกต้องมีคำว่า ​of object ​ต่อ้าสมอ  
 +<sxh delphi;​highlight:​ [12]> 
 +unit Unit1;
  
-<hidden Example-3: เปรียบเทียบการเรียก function โดย Lazarus กับ Delphi > +{$mode objfpc}{$H+}
-<sxh delphi;​highlight:​ [20,​23]>​ +
-Type +
-  Tfunc = function(x:​real):​real of object; ​+
  
-//define polynomial ​function ​f(x) = x^2+2*x-5 +interface 
-function func(x:​real):​real;​+ 
 +uses 
 +  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs; 
 + 
 +type 
 + 
 +  Tfunc = function(x:real):real of object; //​Procedural Type 
 + 
 +  { TForm1 } 
 + 
 +  TForm1 ​class(TForm) 
 +    procedure FormCreate(Sender:​ TObject); 
 +  private 
 + 
 +  public 
 +    function func(x:​real):real; 
 +  end; 
 + 
 +var 
 +  Form1: TForm1; 
 +  function Find_Max(f:​Tfunc;​ xFirst,​xLast,​increment:​real):​real;​ 
 + 
 +implementation 
 + 
 +function Find_Max(f: Tfunc; xFirst, xLast, increment: real): real; 
 +var x,xMax,max:real;
 begin begin
-  ​result:=x*x+2*x-5 ;+  ​x:​=xFirst;​ 
 +  xMax:=x
 +  max:= f(x); 
 +  while x<xLast do 
 +   ​begin 
 +     x:=x+increment;​ 
 +     if f(x)>max then xMax := x; 
 +     max:= f(x); 
 +   ​end;​ 
 +  result:​=f(xMax);
 end; end;
  
-//create function to find the average value between a and b of any function +{$R *.lfm} 
-function average_value(f:Tfunc; a,b:real):real;+ 
 +{ TForm1 } 
 + 
 +procedure TForm1.FormCreate(SenderTObject);
 begin begin
-  ​result:=(f(a)+f(b))/2;+  ​showmessage('​Max value between x 0 to x = 10 is : ' +  
 +  FloatToStr(Find_Max(@func,​0,​10,​0.001)));
 end; end;
-  ​ 
  
-//Call the above function +function ​TForm1.func(x: real): real
-BEGIN +begin 
-  //Lazarus +  ​result:​=-x*x+10*x-10 ; 
-  writeln(average_value(@func,​1,​10));  +end;
-   +
-  ​//Delhpi +
-  ​writeln(average_value(func,​1,​10))+
  
-END.  ​+end. 
 +  
 </​sxh> ​ </​sxh> ​
 </​hidden>​ </​hidden>​
 +----
 +=====Function is Nested=====
 +สำหรับการทำ Nested Function ให้กลายเป็น Procedural Type เพื่อส่งผ่านเป็นตัวแปรนั้น เราสามารถระบุ Function ดังกล่าวได้ตามนี้
  
 +  Type 
 +    TFunc = function(x:​real):​real is Nested ;
 +
 +จะสังเกตได้ว่าคล้ายกับการระบุ Function of Object นั่นเอง เพียงแต่เปลี่ยนจากคำว่า of Object เป็น is Nested แต่อย่างไรก็ตามสิ่งที่แตกต่างกันอีกอย่างหนึ่ง คือ คำสั่งข้างต้น จำเป็นต้องระบุ Compiler Directive ดังนี้ก่อนเสมอ ​
 +
 +  {$modeswitch nestedprocvars}  ​
 +  ​
 +  ​
tutorial/proceduraltype.1536460218.txt.gz · Last modified: 2018/09/09 09:30 by admin