บทท่ี 8 โปรแกรมย่อย ในโลกของความเป็ นจริงองคก์ รที่มีขนาดใหญ่ มีการแบ่งหนา้ ท่ีออกเป็ นฝ่ ายต่าง ๆ เช่น ฝ่ ายบญั ชี ฝ่ ายการตลาด ฝ่ ายบุคคล หรือฝ่ ายผลิต ซ่ึงเหตุผลท่ีตอ้ งแบ่งเพราะงานในบริษทั น้นั มีมีหลายส่วนแต่ละ ส่วนกม็ ีความซบั ซ้อน อีกท้งั งานของแต่ละฝ่ ายก็เป็ นอิสระจากกนั แต่ก็ยงั มีการแลกเปลี่ยนขอ้ มูลระหวา่ ง กนั ในการทางานดว้ ย เช่น บนั ทึกจากฝ่ ายบญั ชีถึงฝ่ ายการตลาด รายงานยอดขายของฝ่ ายขายท่ีแจง้ ให้ ผบู้ ริหารทราบเป็นตน้ ในการเขียนโปรแกรมเพอื่ สร้างแอพพลิเคชนั ก็มีลกั ษณะคลา้ ยกนั จาเป็นอยา่ งย่งิ ที่เราตอ้ งมีการแบ่ง งานออกเป็นส่วน ๆ ซ่ึงแต่ละส่วนก็จะมีหนา้ ที่เฉพาะของตนเอง แตล่ ะส่วนที่มีหนา้ ที่เป็ นอิสระจากกนั น้นั มีการสื่อสารแลกเปลี่ยนข้อมูลระหว่างกัน ซ่ึงเราเรียกหน่วยย่อยๆ ของโปรแกรมท่ีแยกจากกนั น้ีว่า โปรแกรมยอ่ ย ซ่ึงบทน้ีเราจะไดเ้ รียนรู้การสร้าง และใชโ้ ปรแกรมยอ่ ยชนิดตา่ งๆ ดว้ ย VB .NET เน้ือหาบทน้ีจะพดู ถึงรายละเอียดในหวั ขอ้ ดงั ต่อไปน้ี 1. ประเภทของโปรแกรมยอ่ ยในวชิ วลเบสิกดอทเน็ต 2. การใชง้ านโปรแกรมยอ่ ยชนิดซบั รูทีน 3. การใชง้ านโปรแกรมยอ่ ยชนิดฟังกช์ นั 4. การผา่ นค่าตวั แปรในโปรแกรมยอ่ ย 5. การเรียกใชโ้ ปรแกรมยอ่ ยโดยสลบั ลาดบั อาร์กิวเมนต์ 6. ขอบเขตของการทางานในโปรแกรม 8.1 ประเภทของโปรแกรมย่อยในวชิ วลเบสิกดอทเน็ต ในการเขียนโปรแกรม ยอ่ มเกิดการทางานที่ซ้าๆ กนั เราสามารถลดการทางานซ้าๆ น้นั โดยเขียน โปรแกรมยอ่ ยเก็บไว้ เมื่อเราตอ้ งการทางานแบบเดิมอีก เราก็เพียงแต่เรียกโปรแกรมยอ่ ยน้นั มาใชง้ าน ทา ใหล้ ดเวลาการเขียนโปรแกรม และลดความยงุ่ ยากของโปรแกรมท่ีเขียนดว้ ยโปรแกรมยอ่ ยใน VB .NET น้นั มีอยู่ 2 ประเภท (แยกตามรูปแบบของการส่งผลการทางานกลบั มา) ดงั น้ี Sub Routine ซบั รูทีน เป็นโปรแกรมยอ่ ยที่มีเมื่อจบการทางานแลว้ จะไม่มีการส่งผลการทางาน กลบั มาใหเ้ ราทราบ เราจึงมกั เขียนซบั รูทีนท่ีตอ้ งการแตผ่ ลของงาน แตไ่ มต่ อ้ งเนน้ ผลการทางานกลบั มาให้ Function ฟังก์ชนั เป็ นโปรแกรมยอ่ ยท่ีเม่ือจบการทางานแลว้ จะตอ้ งส่งผลการทางานกลบั มา ใหผ้ ทู้ ี่เรียกใชง้ านฟังกช์ นั น้นั บางคร้ังเราอาจเรียกซบั รูทีนวา่ โพรซีเจอร์ (Procedure) ก็ไดซ้ ่ึงกห็ มายถึงโปรแกรมยอ่ ยเหมือนกนั เอกสารประกอบการสอนรายวชิ าการเขยี นโปรแกรมคอมพวิ เตอร์ อ.คฑาวธุ ถวลั ยว์ ลิ าสวงศ์ มหาวทิ ยาลยั ราชภฏั สงขลา
84 8.2 การใช้งานโปรแกรมย่อยชนิดซับรูทนี ซบั รูทีนน้นั เป็นโปรแกรมยอ่ ยที่เราเขียนข้ึนมาเพ่ือทาหนา้ ท่ีอยา่ งใดอยา่ งหน่ึง โดยท่ีซบั รูทีนน้นั จะถูกเรียกใชง้ านตามจุดต่างๆ ของโปรแกรม และเมื่อทางานเสร็จแลว้ จะไมม่ ีการคืนค่าใดๆ กลบั มายงั ผเู้ รียกใชง้ าน ซ่ึงสามารถเขียนโฟลวช์ าร์ตการทางานของซบั รูทีน ไดด้ งั น้ี รูปท่ี 8.1 Flow Chart การใช้งานของซับรูทนี ซบั รูทีนที่เราจะสร้างข้ึนมีรูปแบบการใชง้ านดงั น้ี Sub ชื่อของซับรูทนี (รายการพารามเิ ตอร์ จะมหี รือไม่กไ็ ด้) <คาสัง่ > <คาสั่ง> … … End Sub จากรูปแบบการสร้างซบั รูทีนจะเห็นวา่ บางคร้ังเรากต็ อ้ งส่งขอ้ มลู (ผา่ นรายการพารามิเตอร์) เขา้ ไปใหซ้ บั รูทีนใชป้ ระกอบการทางานภายในดว้ ย เช่น เราจะสร้างซบั รูทีน เพ่อื วาดรูปวงกลม เราก็ ตอ้ งบอกตาแหน่งจุดศูนยก์ ลางของวงกลมที่จะวาด พร้อมดว้ ยความยาวของรัศมีวงกลม เป็นตน้ แต่ บางซบั รูทีนกไ็ มจ่ าเป็นตอ้ งใชข้ อ้ มูลใดๆ ประกอบ แต่ไม่วา่ จะเรียกดว้ ยวิธีการใดๆ เราก็ตอ้ งระบุพารามิเตอร์ที่ตอ้ งใชใ้ ห้ครบถว้ นหากซบั รูทีนน้นั ไม่ ตอ้ งใชพ้ ารามิเตอร์กต็ อ้ งปิ ดวงเลบ็ ทา้ ยชื่อซบั รูทีนน้นั เอกสารประกอบการสอนรายวชิ าการเขยี นโปรแกรมคอมพวิ เตอร์ อ.คฑาวธุ ถวลั ยว์ ลิ าสวงศ์ มหาวทิ ยาลยั ราชภฏั สงขลา
85 ตวั อยา่ ง 8.1 การสร้างและเรียกใชซ้ บั รูทีน Sub Main() Test (1, 2, 3) Test (1000, _ 2000, _ 3000) Console.ReadLine() End Sub Sub Test(ByVal num1 As Integer, _ ByVal num2 As Integer, _ ByVal num3 As Integer) Console.WriteLine(num1) Console.WriteLine(num2) Console.WriteLine(num3) End Sub ตวั อยา่ ง 8.2 การสร้างและเรียกใชซ้ บั รูทีน Sub CalculatePay(ByVal hours As Double, ByVal wage As Decimal) Dim pay As Double pay = hours * wage Console.WriteLine(\"Total Pay: {0}\", pay) End Sub Sub Main() CalculatePay(25, 10) CalculatePay(40, 20) CalculatePay(30, 27.5) Console.ReadLine() End Sub เอกสารประกอบการสอนรายวชิ าการเขยี นโปรแกรมคอมพวิ เตอร์ อ.คฑาวธุ ถวลั ยว์ ลิ าสวงศ์ มหาวทิ ยาลยั ราชภฏั สงขลา
86 8.3 การใช้งานโปรแกรมย่อยชนิดฟังก์ชัน ฟังก์ชนั เป็ นโปรแกรมยอ่ ยที่ต่างจากซบั รูทีนตรงที่จะคืนค่ากลบั มาหาผเู้ รียกใช้ หลงั จาก ฟังก์ชนั ทางานเสร็จแลว้ รูปที่ 8.2 Flow Chart การใช้งานของฟังก์ชัน ฟังกช์ นั ท่ีเราจะสร้างข้ึนมีรูปแบบการใชง้ านดงั น้ี Function ช่ือฟังก์ชัน (รายการพารามเิ ตอร์ จะมหี รือไม่กไ็ ด้ ) As ชนิดข้อมูลทค่ี นื ให้ผ้เู รียก : < คาสัง่ > < คาสง่ั …> : ช่ือฟังกช์ นั = ค่าท่ีคืนกลบั จากรูปแบบการทางานจะเห็นวา่ จะตอ้ งมีการกาหนดชนิดของขอ้ มูลที่ส่งกลบั เสมอ ส่วนจะมีขอ้ มูล ส่งไปประกอบการทางานของฟังกช์ นั หรือไม่น้นั กส็ ุดแลว้ แตก่ ารทางาน ฟังก์ชนั น้นั จะตอ้ งมีการคืนค่ากลบั ให้ผูเ้ รียกใช้งาน โดยปกติเราจะระบุชื่อฟังก์ชันไวใ้ นบรรทดั สุดทา้ ยก่อนจบการทางานของฟังกช์ นั เสมอ และกาหนดค่าให้เพื่อเป็ นค่าท่ีคืนกลบั ให้เรียกใช้ แต่ในบาง ฟังกช์ นั ท่ีมีการจบการทางานไดห้ ลายจุด เช่น ฟังกช์ นั ท่ีมีการใชก้ ารตดั สินใจ ซ่ึงแต่ละทางเลือกอาจจบไม่ เหมือนกนั กต็ อ้ งมีการระบุชื่อฟังกช์ นั พร้อมดว้ ยการกาหนดค่าให้เรียบร้อนในทุกๆ จุดที่จะจบการใชง้ าน ของฟังกช์ นั เอกสารประกอบการสอนรายวชิ าการเขยี นโปรแกรมคอมพวิ เตอร์ อ.คฑาวธุ ถวลั ยว์ ลิ าสวงศ์ มหาวทิ ยาลยั ราชภฏั สงขลา
87 ตวั อยา่ ง 8.3 การสร้างและเรียกใชฟ้ ังกช์ นั Module Module1 Function Area(ByVal radius As Double) As Double Const PI as Double = 3.141 Return (PI * radius ^ 2) End Function Sub Main() Dim a As Double = Area(4.0) Console.WriteLine(a) End Sub End Module ตวั อยา่ ง 8.4 การสร้างและเรียกใชฟ้ ังกช์ นั Module myfunctions Function FindMax(ByVal num1 As Integer, ByVal num2 As Integer) As Integer Dim result As Integer If (num1 > num2) Then result = num1 Else result = num2 End If return result End Function Sub Main() Console.WriteLine(\"Max value is : {0}\", FindMax(100,200)) Console.ReadLine() End Sub End Module เอกสารประกอบการสอนรายวชิ าการเขยี นโปรแกรมคอมพวิ เตอร์ อ.คฑาวธุ ถวลั ยว์ ลิ าสวงศ์ มหาวทิ ยาลยั ราชภฏั สงขลา
88 ตวั อยา่ ง 8.5 การสร้างและเรียกใชฟ้ ังกช์ นั Recursive Module myfunctions Function factorial(ByVal num As Integer) As Integer Dim result As Integer If (num = 1) Then Return 1 Else result = factorial(num - 1) * num Return result End If End Function Sub Main() Console.WriteLine(\"Factorial of 6 is : {0}\", factorial(6)) Console.WriteLine(\"Factorial of 7 is : {0}\", factorial(7)) Console.WriteLine(\"Factorial of 8 is : {0}\", factorial(8)) Console.ReadLine() End Sub End Module 8.4 การผ่านค่าตัวแปรในโปรแกรมย่อย ท่ีผา่ นมาเราจะเห็นวา่ การใชง้ านซบั รูทิน หรือฟังก์ชนั เราอาจจะตอ้ งส่งขอ้ มูลบางอยา่ งไปประกอบ ในการทางานของโปรแกรมย่อย เราเรียกค่าของขอ้ มูลที่ส่งไปให้โปรแกรมย่อย หรือฟังก์ชันว่า อาร์กิวเมนต์ (Argument) ซ่ึงมีรูปแบบการส่งอาร์กิวเมนตอ์ ยู่ 2 รูปแบบ ไดแ้ ก่ 1. Pass by Value เป็นการผา่ นคา่ โดยจะกอ็ ปป้ี คา่ ที่จะผา่ นแลว้ ส่งไปใหโ้ ปรแกรมยอ่ ยท่ี ตอ้ งการแมว้ า่ ภายในโปรแกรมยอ่ ยมีการเปลี่ยนแปลงคา่ ท่ีผา่ นไปใหน้ ้นั ก็จะไม่มีผลใดๆตอ่ ค่าที่ผา่ นซ่ึงอยู่ ภายนอกโปแกรมยอ่ ยน้นั 2. Pass by Reference เป็นการผา่ นคา่ โดยการบอกตาแหน่งในหน่วยความจาท่ีเกบ็ ค่าที่ จะผา่ นน้นั ไวเ้ พราะฉะน้นั ถา้ ภายในโปรแกรมยอ่ ยมีการเปลี่ยนแปลงค่าท่ีผา่ นไปให้ จะส่งผลโดยตรงต่อ ค่าท่ีผา่ นซ่ึงอยภู่ ายนอกโปรแกรมยอ่ ยน้นั เอกสารประกอบการสอนรายวชิ าการเขยี นโปรแกรมคอมพวิ เตอร์ อ.คฑาวธุ ถวลั ยว์ ลิ าสวงศ์ มหาวทิ ยาลยั ราชภฏั สงขลา
89 การผา่ นค่าแบบ Pass by Value น้นั จะเหมือนกบั เราถ่ายสาเนาเอกสารก่อน แลว้ คอ่ ยส่งสาเนาน้นั ไป เพราะฉะน้นั จะทาอะไรกบั สาเนายอ่ มไม่มีผลกบั เอกสารตวั จริง แต่ Pass by Reference น้นั เหมือนกบั การ ส่งเอกสารตวั จริงไปเลยทีเดียวจึงควรระมดั ระวงั ในการใชง้ าน เราอาจเปรียบเทียบง่ายๆ ว่าการส่งผ่านค่าไปยงั โปรแกรมย่อยก็เหมือนกับการขนส่ง โดย พารามิเตอร์ ก็ทาหนา้ ที่เหมือนพาหนะ ( รถยนต์ รถไฟ เคร่ืองบิน เรือ ฯลฯ ) ส่วนอาร์กิวเมนตเ์ ปรียบ เหมือนกบั ส่ิงท่ีถูกขนส่ง ( คน สตั ว์ สินคา้ ฯลฯ ) หลายคนอาจสับสนระหวา่ งคาวา่ อาร์กิวเมนต์ (Argument) และพารามิเตอร์ (Parameter) วา่ ต่างกนั อยา่ งไร ซ่ึงความหมายที่แทจ้ ริงของท้งั สองคา มีดงั น้ี พารามิเตอร์ คือ ชื่อตวั แปรท่ีเกบ็ ขอ้ มลู ที่ใชส้ ่งผา่ นไปใหโ้ ปรแกรมยอ่ ย อาร์กวิ เมนต์ คือ คา่ ของขอ้ มลู ท่ีส่งไปใหก้ บั โปรแกรมยอ่ ย โดยปกติถา้ เราไม่ไดร้ ะบุชนิดของการขนส่งอาร์กิวเมนต์ VB NET จะเลือกรูปแบบ Pass by Value โดยจะสงั เกตเห็นวา่ VB .NET เติมคาวา่ ByVal เขา้ ไปหนา้ พารามิเตอร์แตล่ ะตวั สาหรับการผา่ นอาร์กิวเมนตแ์ บบ Pass by Reference น้นั มกั จะถูกนามาใชต้ ่อเม่ือเราตอ้ งการใหม้ ี ผลต่อตวั แปรท่ีเก็บค่าน้นั ทนั ที หรืออีกกรณีคือ ฟังกช์ นั ท่ีตอ้ งการรีเทิร์นค่ามากกวา่ หน่ึงค่า คือ อาร์เรย์ หรือ Structure โดยเราจะตอ้ งส่งผา่ นอาร์กิวเมนตท์ ่ีเป็ นอาร์เรย์ หรือ Structure แบบ Reference แลว้ ก็รี เทิร์นอาร์เรย์ หรือ Structure น้นั กลบั มา ตวั อย่างการผ่านค่าตวั แปรในโปรแกรมย่อย ตวั อยา่ ง 8.6 การสร้างและเรียกใชซ้ บั รูทีน By Val และ By Ref Module Module1 Sub Main() Dim value As Integer = 1 Example1(value) ‘Pass by Value Console.WriteLine(value) Example2(value) ‘Pass by Reference Console.WriteLine(value) End Sub Sub Example1(ByVal test As Integer) test = 10 End Sub เอกสารประกอบการสอนรายวชิ าการเขยี นโปรแกรมคอมพวิ เตอร์ อ.คฑาวธุ ถวลั ยว์ ลิ าสวงศ์ มหาวทิ ยาลยั ราชภฏั สงขลา
90 Sub Example2(ByRef test As Integer) test = 10 End Sub End Module ตวั อยา่ ง 8.7 การสร้างและเรียกใชซ้ บั รูทีน By Reference Module Module1 Sub swap(ByRef x As Integer, ByRef y As Integer) Dim temp As Integer temp = x x=y y = temp End Sub Sub Main() Dim a As Integer = 100 Dim b As Integer = 200 Console.WriteLine(\"Before swap, value of a : {0}\", a) Console.WriteLine(\"Before swap, value of b : {0}\", b) swap(a, b) Console.WriteLine(\"After swap, value of a : {0}\", a) Console.WriteLine(\"After swap, value of b : {0}\", b) Console.ReadLine() End Sub End Module 8.5 การเรียกใช้โปรแกรมย่อยโดยสลบั ลาดับอาร์กวิ เมนต์ ขอ้ จากดั อยา่ งหน่ึงของการเรียกใชง้ านโปรแกรมย่อยก็คือ เราตอ้ งเรียกโปรแกรมย่อยโดยกาหนด อาร์กิวเมนตใ์ ห้ถูกตอ้ งตามท่ีกาหนดไว้ ไม่เช่นน้นั ก็จะมีขอ้ ความแสดงความผิดพลาดจาก VB .NET แจง้ ใหท้ ราบ VB.NET ไดท้ ลายขอ้ จากดั ของการเรียกใชโ้ ปรแกรมยอ่ ยในแบบเดิมๆ โดยใหเ้ ราสามารถสลบั ตา แหน่งอาร์กิวเมนตไ์ ด้ โดยตอ้ งระบุชื่อตวั แปรพร้อมกบั คา่ ท่ีส่งผา่ นน้นั เอกสารประกอบการสอนรายวชิ าการเขยี นโปรแกรมคอมพวิ เตอร์ อ.คฑาวธุ ถวลั ยว์ ลิ าสวงศ์ มหาวทิ ยาลยั ราชภฏั สงขลา
91 ตัวอย่าง 8.8 การประกาศซบั รูทีนช่ือ MyData Sub MyData(ByVal Name As String, ByVal Age As Integer, ByVal Email As String) Console.Write(Name) Console.Write(Age) Console.WriteLine(Email) End Sub Sub Main() MyData(\"Katawut Tawanwilaswong\", 28, \"[email protected]\") 'ทดลองเรียกโดยในแบบสลบั ตาแหน่งการเรียก MyData(Age:=30, Email:=\"[email protected]\", Name:=\"Katawut Tawanwilaswong\") MyData(Email:=\"[email protected]\", Name:=\"Peerapol\", Age:=31) Console.ReadLine() End Sub 8.6 ขอบเขตของการทางานในโปรแกรม การท่ีเราแบ่งโปรแกรมที่เขียนข้ึนเป็ นโปรแกรมยอ่ ยน้นั ยอ่ มแสดงวา่ โปรแกรมถูกแบ่งออกเป็ น ส่วนต่างๆ ที่อิสระจากกนั ( แต่มีส่วนที่คอยเชื่อมต่อกนั ) การท่ีเป็ นอิสระจากกนั ทาให้เราสามารถสร้างตวั แปรที่มีช่ือเหมือนกนั ข้ึนมาใชง้ านไดซ้ ่ึง VB .NET สามารถแยกแยะความแตกต่างของตวั แปรท่ีสร้างข้ึน ไดด้ ว้ ยสิ่งท่ีเรียกวา่ ขอบเขตของโปรแกรม (Scope) ขอบเขตของโปรแกรมท่ีใชง้ านใน VB .NET มีอยู่ 4 ระดบั เรียงลาดบั จากขอบเขตที่ใหญ่ท่ีสุดไป หาขอบเขตท่ีนอ้ ยที่สุด ตงั น้ี Global เป็นขอบเขตที่มองเห็นไดท้ ้งั โปรเจก็ ต์ Module เป็นขอบเขตระดบั ของแต่ละไฟลใ์ นโปรเจก็ ต์ Procedure เป็นขอบเขตระดบั โปรแกรมยอ่ ย (ท้งั ในฟังกช์ นั และซบั รูทีน) Block เป็นขอบเขตตวั แปรที่เล็กท่ีสุด จะมีผลอยรู่ ะหวา่ งบล็อกของคาสั่งหน่ึง การประกาศตวั แปรสาหรับการเขียนโปรแกรมท่ีดีน้นั ควรจะประกาศในขอบเขตเท่าที่จาเป็ นตอ้ ง ใช้งาน การประกาศตวั แปรระดบั Global มากๆ ไม่ใช่เรื่องดีเลย เพราะแอพพลิเคชันเสียเน้ือที่ หน่วยความจาถาวรไปตลอดเพ่ือเก็บตวั แปรน้นั (ย่ิงเยอะยิ่งเสียพ้ืนที่มาก) นอกจากน้ีการมีตวั แปรระดบั Global มากๆ ยงั ยากในการตรวจสอบแกไ้ ขโปรแกรมในภายหลงั อีกดว้ ย เอกสารประกอบการสอนรายวชิ าการเขยี นโปรแกรมคอมพวิ เตอร์ อ.คฑาวธุ ถวลั ยว์ ลิ าสวงศ์ มหาวทิ ยาลยั ราชภฏั สงขลา
Search
Read the Text Version
- 1 - 9
Pages: