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
Last revision Both sides next revision
tutorial:proceduraltype [2018/09/09 09:31]
admin
tutorial:proceduraltype [2018/10/28 12:23]
admin [Function of Object]
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 ====
  
-<hidden Example-2: แก้ปัญหาโดยการะกตัวแปร Procedural Type ก่อน +ข้อสังเต การใส่ function เขาไสำรับ lazarus กับ delphi จะแตกต่งกัน ​โดย ​Lazarus จะใช้การส่งค่าผ่าน pointer ดังนั้นจึงต้องมีเคื่องหมย @ นำหน้าชื่อ function แ่สำหรบ delphi สามาถส่งชื่อ ​function เข้าไปได้เลย ดูตัวอย่างที่ 2 
-<sxh delphi;>​ + 
-Type +<hidden Example-2: Function Finding Max Value (Delphi) ​
-  Tfunc = function(x:​real):​real; ​+<sxh delphi;highlight: [3,32]
 +PROGRAM Find_MaxValue_Of_Function;​ 
 + 
 +{$MODE delphi} 
 + 
 +TYPE 
 +  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(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; ​+
  
-//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; 
 + 
 +end.
   ​   ​
-  //Delhpi 
-  writeln(average_value(func,​1,​10)); ​ 
- 
-END.  ​ 
 </​sxh> ​ </​sxh> ​
 </​hidden>​ </​hidden>​
 +----
 +=====Function is Nested=====
  
tutorial/proceduraltype.txt · Last modified: 2018/10/28 12:32 by admin