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:36]
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: 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>​
 +\\ 
  
 +====ข้อแตกต่างระหว่าง Lazaus กับ Delphi ====
  
-จาก Example-1 จะเห็นว่า ราไม่สาารส่งตัวแปรทีเป็น procedure/​function เข้ไปใน Argument ของ function average_value ได้ จึงจำเป็นต้องมีารประการ ​Type ของ function ก่อน ังตัวอย่างอไปนี้+ข้อสังเกต ​การใส่ function เข้าไำหรับ lazarus กับ delphi จะแตกต่งกัน โดย Lazarus จะใช้การส่งค่าผ่าน ​pointer ​ังนัจึงต้องมีเครื่องหมย @ นำหน้าชื่อ function แต่สำหับ delphi สามารถส่ชื่อ ​function เข้าไปไ้เลย ดูตัวอย่างที่ 2
  
-<hidden Example-2: ​แก้ปัญหาโดยการประกาศตัวแปร Procedural Type ก่อน ​+<hidden Example-2: ​Function Finding Max Value (Delphi) ​
-<sxh delphi;>​ +<sxh delphi;highlight: [3,32]
-Type +PROGRAM Find_MaxValue_Of_Function;​ 
-  Tfunc = function(x:​real):​real; ​+ 
 +{$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.1536460564.txt.gz · Last modified: 2018/09/09 09:36 by admin