ทั้งคู่ทำหน้าที่เป็นโปรแกรมย่อยเหมือนกัน แต่มีความแตกต่างกันอยู่ดังนี้
Procedure โดยปกติจะมีอยู่ 2 แบบ คือ แบบรับค่า input กับแบบไม่รับค่า input
Topic | Format |
---|---|
Procedure แบบไม่รับค่า Input | procedure ProcedureName; begin {Do something} end; |
Procedure แบบรับค่า Input | procedure ProcedureName(Arg1,Arg2:integer; Arg3:real); begin {Do something} end; |
รูปแบบของ function นั้น จะคล้ายกับ procedure ทุกประการ คือมีทั้งแบบรับค่า input กับแบบไม่รับค่า input
แต่โดยทั่วไปแล้ว function มักจะถูกใช้งานโดยการรับค่า input (เพราะถ้าไม่มีการรับค่า ก็ไม่ต่างจากการใช้ค่าคงที่)
อย่างไรก็ตาม สิ่งที่ขาดไม่ได้เลยสำหรับการประกาศ function คือ ต้องมีการส่งค่า output กลับด้วยเสมอ
ตัวแปรที่ใช้รับค่าเพื่อแสดงค่า output มีได้ 2 แบบ คือ
Topic | Format |
---|---|
Function แบบใช้ตัวแปรที่ชื่อ result เป็น Output | function FunctionName(Arg1,Arg2:integer; Arg3:real):integer; begin result:= {Do something}; end; |
Function แบบใช้ตัวแปรที่เป็นชื่อของฟังก์ชั่นเอง เป็น Output | function FunctionName(Arg1,Arg2:integer; Arg3:real):integer; begin FunctionName:= {Do something}; end; |
จากประสบการณ์ของผม ขอแนะนำให้ใช้ result แทนชื่อของ Function ครับ เพราะจะง่ายในการแก้ใขชื่อ Function ในภายหลัง
หลังจากการประกาศ uses แล้ว Procedure/Function ที่เป็น Global Scope สามารถประกาศไว้ ณ ส่วนไหนของโปรแกรมก็ได้ แต่โดยปกติแล้ว ผมขอแนะนำให้ประกาศทีหลังสุด (หลังจากประกาศ var) แต่ถ้าหากเป็น Function/Procedure ที่มาจาก Shared Library ผมขอแนะนำให้วางไว้แรกสุด (ต่อจากการประกาศ uses)
การเรียกใช้ Procedure นั้นง่ายมาก เพียงแค่ใส่ชื่อ Procedure นั้นๆ (พร้อมกับ Input Parameters ถ้ามี) ได้เลย ยกตัวอย่างเช่น
สำหรับการเรียกใช้ Function นั้นก็คล้ายกับการเรียกใช้ Procedure แต่มีข้อแตกต่างอีกอย่างหนึ่ง คือ Function ให้ค่า Output ด้วย
คือ Function/Procedure ที่เป็น Local Scope ซ้อนอยู่ใน Function/Procedure อื่น
การส่งผ่าน Parameters เข้าไปใน Procedure/Function มี 2 แบบ คือ By Value และ By Reference
การใส่ตัวแปรแบบทั่วไป คือ การส่งผ่าน Parameter ในแบบ By Value
procedure DoItA(X:integer); begin X:=10; writeln('X = ',X); end;
เราสามารถใส่ var หน้า Parameter เพื่อให้กลายเป็น By Reference ได้ดังนี้
procedure DoItB(var X:integer); begin X:=10; writeln('X = ',X); end;
คือ การประกาศ 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 อีก ดังตัวอย่างต่อไปนี้
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.