This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
tutorial:procedureandfunction [2018/10/28 10:21] admin [รูปแบบของ Function] |
tutorial:procedureandfunction [2019/01/06 16:54] (current) admin |
||
|---|---|---|---|
| Line 71: | Line 71: | ||
| </sxh> | </sxh> | ||
| </hidden> | </hidden> | ||
| - | \\ | ||
| <hidden Example-4: Function แบบใช้ตัวแปรที่เป็นชื่อของฟังก์ชั่นเอง เป็น Output> | <hidden Example-4: Function แบบใช้ตัวแปรที่เป็นชื่อของฟังก์ชั่นเอง เป็น Output> | ||
| <sxh delphi;> | <sxh delphi;> | ||
| Line 85: | Line 84: | ||
| \\ \\ | \\ \\ | ||
| - | =====การประกาศ Procedure/Function===== | + | =====การประกาศและการเรียกใช้ Procedure/Function===== |
| - | หลังจากการประกาศ uses แล้ว Procedure/Function ที่เป็น Global Scope สามารถประกาศไว้ ณ ส่วนไหนของโปรแกรมก็ได้ แต่โดยปกติแล้ว ผมขอแนะนำให้ประกาศทีหลังสุด (หลังจากประกาศ var) แต่ถ้าหากเป็น Function/Procedure ที่มาจาก Shared Library ผมขอแนะนำให้วางไว้แรกสุด (ต่อจากการประกาศ uses) | + | หลังจากการประกาศ uses แล้ว Procedure/Function ที่เป็น Global Scope สามารถประกาศไว้ ณ ส่วนไหนของโปรแกรมก็ได้ แต่โดยปกติแล้ว ผมขอแนะนำให้ประกาศทีหลังสุด (หลังจากประกาศ var) แต่ถ้าหากเป็น Function/Procedure ที่มาจาก Shared Library ผมขอแนะนำให้วางไว้แรกสุด (ต่อจากการประกาศ uses) \\ |
| + | |||
| + | การเรียกใช้ Procedure นั้นง่ายมาก เพียงแค่ใส่ชื่อ Procedure นั้นๆ (พร้อมกับ Input Parameters ถ้ามี) ได้เลย ยกตัวอย่างเช่น | ||
| + | |||
| + | <hidden Example-5: Calling Procedures> | ||
| + | <sxh delphi> | ||
| + | Program SayHellow; | ||
| + | |||
| + | procedure HelloWorld; | ||
| + | begin | ||
| + | writeln('HelloWorld'); | ||
| + | end; | ||
| + | |||
| + | procedure SayHello(sName:string); | ||
| + | begin | ||
| + | writeln('Hello'+ sName); | ||
| + | end; | ||
| + | |||
| + | Begin | ||
| + | HelloWorld; //Calling HelloWorld | ||
| + | SayHello('Mr. Smith'); //Calling Procedure | ||
| + | End. | ||
| + | </sxh> | ||
| + | </hidden> | ||
| \\ | \\ | ||
| + | |||
| + | สำหรับการเรียกใช้ Function นั้นก็คล้ายกับการเรียกใช้ Procedure แต่มีข้อแตกต่างอีกอย่างหนึ่ง คือ Function ให้ค่า Output ด้วย | ||
| + | \\ \\ | ||
| + | |||
| =====Nested Function/Procedure===== | =====Nested Function/Procedure===== | ||
| คือ Function/Procedure ที่เป็น Local Scope ซ้อนอยู่ใน Function/Procedure อื่น\\ | คือ Function/Procedure ที่เป็น Local Scope ซ้อนอยู่ใน Function/Procedure อื่น\\ | ||
| - | <hidden Example-5: Nested Function> | + | <hidden Example-6: Nested Function> |
| <sxh delphi;highlight: [4-10]> | <sxh delphi;highlight: [4-10]> | ||
| procedure SolvePolynomial(A,B,C:real); | procedure SolvePolynomial(A,B,C:real); | ||
| Line 121: | Line 147: | ||
| \\ \\ | \\ \\ | ||
| + | |||
| + | =====Passing Parameters===== | ||
| + | การส่งผ่าน Parameters เข้าไปใน Procedure/Function มี 2 แบบ คือ By Value และ By Reference | ||
| + | * **By Value** คือ ส่งเฉพาะค่าของ Parameter เข้าไปใน Procedure/Function โดยหากมีการเปลี่ยนแปลงค่าใดๆใน Procedure/Function นั้น จะ__**ไม่เปลี่ยนแปลง**__ต่อค่าที่แท้จริงของ Parameter สำหรับการรับค่าแบบปกติ | ||
| + | * **By Reference** คือ หากมีการเปลี่ยนแปลงค่าใดๆของ Parameter ใน Procedure/Function นั้น จะ__**เปลี่ยนแปลง**__ค่าที่แท้จริงของ Parameter ด้วย | ||
| + | |||
| + | ====By Value==== | ||
| + | การใส่ตัวแปรแบบทั่วไป คือ การส่งผ่าน Parameter ในแบบ By Value | ||
| + | |||
| + | <sxh delphi;> | ||
| + | procedure DoItA(X:integer); | ||
| + | begin | ||
| + | X:=10; | ||
| + | writeln('X = ',X); | ||
| + | end; | ||
| + | </sxh> | ||
| + | |||
| + | ====By Reference==== | ||
| + | เราสามารถใส่ var หน้า Parameter เพื่อให้กลายเป็น By Reference ได้ดังนี้ | ||
| + | |||
| + | <sxh delphi;> | ||
| + | procedure DoItB(var X:integer); | ||
| + | begin | ||
| + | X:=10; | ||
| + | writeln('X = ',X); | ||
| + | end; | ||
| + | </sxh> | ||
| + | |||
| + | |||
| + | <hidden Example-7: Passing Parameters (By Value, By Reference)> | ||
| + | <sxh delphi;> | ||
| + | program Passing_Param; | ||
| + | |||
| + | var A,B:integer; | ||
| + | |||
| + | procedure DoItA(X:integer); //By Value | ||
| + | begin | ||
| + | X:=100; | ||
| + | writeln('DoItA, X = ',X); | ||
| + | end; | ||
| + | |||
| + | procedure DoItB(var X:integer); //By Reference | ||
| + | begin | ||
| + | X:=200; | ||
| + | writeln('DoItB, X = ',X); | ||
| + | end; | ||
| + | |||
| + | begin | ||
| + | A:=1; | ||
| + | B:=2; | ||
| + | |||
| + | writeln('A = ',A); | ||
| + | writeln('B = ',B); | ||
| + | |||
| + | DoItA(A); | ||
| + | DoItB(B); | ||
| + | |||
| + | writeln('A = ',A); | ||
| + | writeln('B = ',B); | ||
| + | |||
| + | readln(); | ||
| + | end. | ||
| + | </sxh> | ||
| + | |||
| + | Compiled Results: | ||
| + | |||
| + | A = 1 | ||
| + | B = 2 | ||
| + | DoItA, X = 100 | ||
| + | DoItB, X = 200 | ||
| + | A = 1 | ||
| + | B = 200 | ||
| + | | ||
| + | </hidden> | ||
| + | \\ | ||
| + | |||
| + | =====Forward Declaration===== | ||
| + | คือ การประกาศ Procedure/Function ล่วงหน้าเพื่อให้ทุก Procedure/Function สามารถเรียกใช้งานกันและกันได้หมด สาเหตุที่ต้องทำแบบนี้เพราะว่า โดยปกตินั้น Compiler จะอ่าน source code จาก บนลงล่าง ดังนั้น หากมี Procedure/Function ตัวใดตัวหนึ่งเรียกใช้งาน Procedure/Function ตัวอื่นที่ยังไม่ได้ประกาศ จะทำให้เกิด Error \\ | ||
| + | |||
| + | รูปแบบการประกาศสำหรับ Program จะมีคำว่า forward ต่อท้ายดังนี้ | ||
| + | |||
| + | Procedure DoSomething; forward; | ||
| + | |||
| + | สำหรับ Unit นั้น FPC บังคับให้ต้องมีการทำ forward declaration ทุกครั้งก่อนเสมอ เพราะ unit อื่นหรือ program ที่มีการ uses unit ดังกล่าวนั้น จะเข้าถึง Procedure/Function ได้เฉพาะส่วนที่เป็น interface เท่านั้น ไม่สามารถเข้าถึงส่วน implementation โดยตรงได้ ดังนั้นจึงต้องประกาศล่วงหน้าในตำแหน่งใต้คำว่า interface เสมอ โดยการประกาศจะไม่มีคำว่า forward ต่อท้ายเหมือนของ program อีก ดังตัวอย่างต่อไปนี้ | ||
| + | |||
| + | <sxh delphi;> | ||
| + | unit Unit1; | ||
| + | |||
| + | interface | ||
| + | //Forward declaration | ||
| + | procedure First; | ||
| + | procedure Second; | ||
| + | |||
| + | implementation | ||
| + | |||
| + | procedure First; | ||
| + | begin | ||
| + | writeln('Hello First'); | ||
| + | Second; | ||
| + | end; | ||
| + | |||
| + | procedure Second; | ||
| + | begin | ||
| + | writeln('Hello Second'); | ||
| + | end; | ||
| + | end. | ||
| + | </sxh> \\ | ||
| + | |||
| + | |||
| + | <hidden Example-8: Forward Declarations on Simple Program> | ||
| + | __**อธิบาย**__ - ตัวอย่างนี้ มีการประกาศโปรแกรมย่อย ชื่อ Second ล่วงหน้าในบรรทัดที่ 4 เพื่อให้โปรแกรมย่อยที่ชื่อ First ได้รู้จัก Second ก่อน แน่นอนว่าหากตัด code ในบรรทัดที่ 4 ออกไปแล้ว สิ่งที่จะตามมาคือ เมื่อ compiler อ่านจนมาถึง First ก็จะฟ้องทันทีว่าไม่สามารถหา Second เจอ | ||
| + | |||
| + | <sxh delphi;highlight: [4]> | ||
| + | program FWD_Declaration; | ||
| + | |||
| + | //Forward declarations | ||
| + | procedure Second; forward; | ||
| + | |||
| + | //Implementations | ||
| + | procedure First; | ||
| + | begin | ||
| + | writeln('Hello First'); | ||
| + | Second; | ||
| + | end; | ||
| + | |||
| + | procedure Second; | ||
| + | begin | ||
| + | writeln('Hello Second'); | ||
| + | end; | ||
| + | |||
| + | begin | ||
| + | First; | ||
| + | readln(); | ||
| + | end. | ||
| + | </sxh> | ||
| + | |||
| + | Compiled Results: | ||
| + | |||
| + | Hello First | ||
| + | Hello Second | ||
| + | | ||
| + | </hidden> | ||
| + | \\ | ||