หากมีคำถาม ขอให้ไปโพสต์ลง เว็บบอร์ดจีทูจีเน็ตดอตคอม ตัวใหม่แทนน่ะครับ

หรือติดต่อเข้ามาทาง Inbox ที่ เฟซบุ๊ค ผมครับ

หน้าหลัก
ข่าวสาร - บทความ ทั้งหมด
VB 6/VB.Net
ASP/ASP.Net
จับฉ่ายคอมพิวเตอร์
เรียนรู้ผ่าน Flash Movie
บทความที่มีผู้ตอบล่าสุด  
 RSS Feeds
 ดาวน์โหลดโปรแกรม RSS Reader ได้ที่นี่ ...   Download โปรแกรม RSS Reader

Forum - www.g2gnet.com
Webmaster - www.g2gnet.com
Visitors - Session views
 5 5 9 1 7 5 6

7 ธันวาคม พ.ศ.2549
116 Users On-Line.
Visitors - Page views
 8 9 4 6 8 0 6
1 กุมภาพันธ์ พ.ศ.2551

Google   
เว็บ g2gnet.com
ขนาดตัวอักษร:  

เรื่องของโปรแกรมย่อย (อีกที) ... Sub Program, Routine, Procedure หรือ Function

Category »  VB 6/VB.Net
โดย : Webmaster เมื่อ 22/5/2551 11:44:00
(อ่าน : 33735) 
เรื่องนี้ผมเคยเขียนไปแล้วแหละครับ แต่ที่ต้องนำออกมาไว้ตรงนี้ ก็เพราะเวลาที่ผม Monitor ดูพี่น้องเข้ามาตักตวงความรู้ในเว็บไซต์ของผม หลายคนอาจหาสิ่งที่ต้องการไม่เจอ เพราะตอนแรกที่ทำก็ไม่ได้คาดเลยว่า Ranking จะแจ่มอย่างนี้ ก็ทำเอามันๆ สนุกๆไป ไม่ได้คิดอะไรมาก ... ในหลายฉากหลายตอนผมเองได้กล่าวถึงเรื่องของ โปรแกรมย่อย (Sub Program) และ บางบทความก็เป็นเจตนาของผมเองที่ต้องการให้พี่น้อง ได้ทำการแปลงส่วนของการทำงานซ้ำๆให้กลายมาเป็นโปรแกรมย่อยแทน เพื่อจัดระเบียบ ลดความซ้ำซ้อนของโค้ด การตรวจสอบการทำงานของโปรแกรมทำได้ง่าย สามารถทำการตัดต่อเพื่อนำไปใช้ประโยชน์อย่างอื่นได้อย่างคล่องตัว จะเห็นได้ชัดเจนจากการเปิด หรือ ปิดการเชื่อมต่อข้อมูล ที่เก็บไว้ใน Module เมื่อนำไปใช้งานกับโปรเจคอื่นๆ ก็แค่ดึงไฟล์ Module (.BAS) ไปซ่ะงั้นเลย และดัดแปลงอีกเพียงเล็กน้อย ไม่ต้องมามัวงมโข่งเขียนขึ้นใหม่ให้เสียเวลา
    แทบจะทุกๆภาษาคอมพิวเตอร์ โปรแกรมย่อยจะแบ่งออกเป็น 2 แบบคือ
  1. โปรแกรมย่อย ชื่อเรียกมันเยอะขึ้นกับภาษาที่ใช้ เช่น Sub Program, Sub Routine หรือ Procedure
  2. ฟังค์ชั่น (Function)
    ทั้งสองแบบ บางที (บ่อยครั้ง) เราจะเรียกมันว่าเป็น "คำสั่ง" โดยกำเนิดเกิดจาก
  1. ติดมากับตัวแปลภาษา (Build In) เช่น Left$("ABC", 1), Mid$("ABC", 2, 1) หรือ MsgBox() ที่เราคุ้นเคยนี่แหละ ใน Visual Basic การเกิดเหตุการณ์ (Events) นั่นก็ถือว่าเป็นโปรแกรมย่อยได้ทั้ง 2 แบบเหมือนกัน ส่วน WinAPI มักจะเป็นเรื่องของฟังค์ชั่นครับผม
  2. สร้างขึ้นมาใหม่ เช่น ตัวอย่างของเรื่องนี้แหละครับ
    ความเหมือนของทั้งสองแบบ คือ สามารถส่งค่า (Argument) ผ่านไปยังโปรแกรมย่อยได้ การส่งค่าก็มีอีก 2 แบบ คือ
    (คำว่า Argument กับ Parameter 2 ตัวนี้ ไม่ต้องไปสนใจใยดีมันนักหรอกครับ งง และ สับสนในชีวิตเปล่าๆ ... ขอให้รู้แต่เพียงว่า เมื่อมีการส่งค่าไปยังโปรแกรมย่อย และ ค่าที่ว่านี้จะต้องกำหนดให้เป็นตัวแปรชนิดเดียวกัน ... ก็พอแล้ว)
  1. Pass By Value คือ การส่งค่าผ่านตัวแปรไปตรงๆ เช่น
    
    Private Sub Form_Load()
    Dim NumberOfTimes As Integer
        
        NumberOfTimes = 3
    	
        ' พิจารณาเฉพาะตัวแปร NumberOfTimes พอครับ ... พี่น้อง
        ' ส่งค่า NumberOfTimes ซึ่งมีค่าเท่ากับ 3 ไปเลย
        Call ShowMessage("Hello, World", NumberOfTimes)
        

    Memory Address คือ ตัวเลขสมมุติให้เข้าใจง่าย
    ชื่อตัวแปร คือ มุมมองมาจากภาษาระดับสูง ... ไม่ใช่อินเฮอริตง ริแตนซ์ (Inheritance) เพื่อสืบทอดแต่อย่างใด ...
    แซว .Net น่ะ 55555+
    ' ให้แสดงผลค่าของ NumberOfTimes MsgBox NumberOfTimes ' คำตอบคือ 3 เนื่องจากเป็นการส่งค่า (คัดลอกค่านั่นเแหละ) ไปโดยตรง ไม่ได้ถูกชี้ไปโดยตำแหน่งที่เก็บข้อมูล (Memory Address) ' ว่าง่ายๆ ตำแหน่งที่เก็บข้อมูลของ NumberOfTimes กับ Times มันอยู่คนละที่กัน ... ไม่เกี่ยวข้องกัน End Sub
    ' ดังนั้นตัวแปรเพื่อรับค่า (Parameter) Times จึงมีค่าเท่ากับ 3 ด้วย (กระบวนการนี้เป็นการคัดลอกข้อมูลมาไงล่ะครับ ... พี่น้อง) Sub ShowMessage(ByRef Text As String, ByVal Times As Integer) Dim i As Integer For i = 1 To Times Debug.Print Text Next ' เปลี่ยนค่าตัวแปร Times ให้เท่ากับ 23 Times = 23 End Sub
  2. Pass By Reference คือ การส่งค่าผ่านตำแหน่งหน่วยความจำ ... อธิบายเป็นตัวอักษรยากครับ ขอให้พิจารณาจากตัวอย่างแล้วกัน
    
    Private Sub Form_Load()
    Dim NumberOfTimes As Integer
        
        NumberOfTimes = 3
    	
        ' อันนี้เป็นการส่งค่าตำแหน่งที่เก็บข้อมูลของตัวแปร NumberOfTimes ไป
        Call ShowMessage("Hello, World", NumberOfTimes)
        

    ไปกระทำใดๆกับ ข้อมูลที่อยู่ในตำแหน่ง 10001 ก็จะมีผลให้เกิดการเปลี่ยนแปลงตามไปด้วย
    ' เมื่อกลับมาจากการทำงานโปรแกรมย่อย MsgBox NumberOfTimes ' คำตอบคือ 23 เนื่องจากถูกชี้ไปโดยตำแหน่งที่เก็บข้อมูล (Memory Address) ' ตำแหน่งที่เก็บข้อมูลของ NumberOfTimes กับ Times มันอยู่ที่เดียวกันครับ ... พี่น้อง ' แต่ชื่อที่เราอ้างอิงถึงมันคนละชื่อกัน ก็เท่านั้น ... นี่แหละคือข้อดีของภาษาระดับสูง ' ใครที่ศึกษาภาษาระดับกึ่งต่ำกึ่งสูง เช่น Assembly มา อย่างนี้เรียกว่าขนมเลยครับ End Sub
    ' รับค่า Argument เข้ามาแบบอ้างอิงตำแหน่ง Sub ShowMessage(ByRef Text As String, ByRef Times As Integer) Dim i As Integer For i = 1 To Times Debug.Print Text Next Times = 23 ' เปลี่ยนค่าตัวแปร Times ให้เท่ากับ 23 ' เมื่อเป็นการอ้างอิงตำแหน่งของการเก็บข้อมูล ' ดังนั้นเมื่อส่งค่าผ่าน ByRef ตำแหน่งของ Times กับ NumberOfTimes มันคือที่ๆเดียวกัน ' แต่ VB มันเป็นภาษาระดับสูง เราจึงไม่ต้องไปสนใจว่ามันอยู่ที่ Address ที่เท่าไร End Sub
    ความแตกต่างของ Sub Program และ Function ก็คือ
  1. Sub Program ไม่สามารถคืนค่ากลับมาได้
  2. Function สามารถคืนค่ากลับมาได้ (Return)

จงเชื่อในสิ่งที่ทำ ... How To and Do it ... Now
Option Explicit Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Var() As Any) As Long Private Sub Form_Load() Dim NumberOfTimes As Integer NumberOfTimes = 3 ' ===================== Pass By Value ================== Debug.Print "Pass by Value Address : " & VarPtr(NumberOfTimes) Call ShowMessageByVal("Hello, World", NumberOfTimes) ' ===================================================== ' ================= Pass By Reference ================== Debug.Print "Pass by Reference Address : " & VarPtr(NumberOfTimes) Call ShowMessageByRef("Hello, World", NumberOfTimes) ' ===================================================== End Sub Sub ShowMessageByVal(ByRef Text As String, ByVal Times As Integer) Debug.Print "Address ที่โปรแกรมย่อย : " & VarPtr(Times) End Sub Sub ShowMessageByRef(ByRef Text As String, ByRef Times As Integer) Debug.Print "Address ที่โปรแกรมย่อย : " & VarPtr(Times) End Sub

แสดงตำแหน่งข้อมูลทั้งแบบ Pass by Value (ตำแหน่งข้อมูลไม่ตรงกัน) และ
แบบ Pass by Reference (ตำแหน่งข้อมูลอันเดียวกัน)

จี ทู จี เน็ต ดอต คอม - g2gNet Dot Com
เลขทะเบียนพาณิชย์อิเล็กทรอนิกส์ 0407314800231
CopyLeft © 2004 - 2099 g2gNet.Com All rights reserved.
Email: [email protected] หรือ โทร. 08-6862-6560