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:47]
admin
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: ​Use a function as Input Argument - Wrong Method ​>+<hidden Example-1: ​Function Finding Max Value>
 **ตัวอย่าง** การส่ง function เข้าไปอีก function หนึ่ง \\ **ตัวอย่าง** การส่ง function เข้าไปอีก function หนึ่ง \\
-__ข้อสังเกต__: ​ปัญหาการส่ง่าน ​func เข้าไปใน average_value ไม่สามารำได้ +__ข้อสังเกต__: ​การหาค่าสูงสุดของ function โดยการสร้าง function ทีมีชื่อว่า Find_Max จะสัเกตว่าภายใน function ดังกล่าว มีการเรียก function จากภายนอกเข้ามาคำนวณ ซึงเรียกว่า f() ดังนั้นเราจึงต้องกำหนดให้ f() เป็นตัวแปรชนิด Procedural Type\\ 
-<sxh delphi;>+ำหรับ Lazarus การเรียก func เข้ามาใน Find_Max ในบรรทที่ 30 จะเป็นการเรียกผ่าน Pointer ดังนันจึงต้องใส่ @ นำหน้าชื่อ function เสมอ 
 + 
 +{{ :​introduction:​plot_polynomial.png?​400 |}} 
 +  
 +<sxh delphi;highlight: [4,13,30]> 
 +PROGRAM Find_MaxValue_Of_Function;​ 
 + 
 +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(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>​
 ---- ----
  
-====ข้อแต่างระห่าง Lazaus ​กับ Delphi ====+=====Function of Object===== 
 +ตัวอย่างข้างบนนั้น ใช้ได้ับกรณีที่ function ถูกประกศเป็น Global Scope เท่านั้น (จะสัเกตว่า func ไม่ได้อยู่ภายใต้ Class หรือ Object ใดๆ) ในกรณีที่ function ถูกประกาศเป็น Local Scope ภายใต้ Class รือ Object ใดๆ จะต้องเปลียนกรประาศ Type ใหม่เป็นดงนี้
  
-ข้อสังเกต การใส่ ​function ​เข้าไปสำหรับ lazarus กับ delphi จะแตกต่างกัน โดย Lazarus จะใช้การส่งค่าผ่าน pointer ดังนั้นจึงต้องมีเครื่องหมาย @ นำหน้าชื่อ function แต่สำหรับ delphi สามารถส่งชื่อ function เข้าไปได้เลย ดูตัวอย่างที่ 3+  Type  
 +    TFunc = function(x:​real):​real of Object ;
  
-<hidden Example-3: ​ปรียบเทียการรียก function โดย Lazarus กับ Delphi > +<hidden Example-3: ​Function of Object (TForm)>​ 
-<sxh delphi;​highlight:​ [19,22]> +**ตัวอย่าง** การประกาศ Procedural Type ของ function ​ที่ประกาศภาใต้ Form1\\ 
-Type +__ข้อสังเกต__: ​การะกาศจะต้องมคำว่า of object ต่อท้าเสมอ ​ 
-  Tfunc = function(x:​real):​real+<sxh delphi;​highlight:​ [12]> 
 +unit Unit1;
  
-//define polynomial ​function ​f(x) = x^2+2*x-5 +{$mode objfpc}{$H+} 
-function func(x:​real):​real;​+ 
 +interface 
 + 
 +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 
-BEGIN 
-  //Lazarus 
-  writeln(average_value(@func,​1,​10)); ​ 
-  ​ 
-  //Delhpi 
-  writeln(average_value(func,​1,​10)); ​ 
  
-END.  ​+function TForm1.func(x: real): real; 
 +begin 
 +  result:​=-x*x+10*x-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.1536461255.txt.gz · Last modified: 2018/09/09 09:47 by admin