พอยเตอร์ (Pointer)

          พอยเตอร์คือต้นฉบับของชนิดข้อมูล เป็นชนิดข้อมูลที่สร้างจากข้อมูลมาตรฐานขนิดหนึ่งค่าขงอมันก็คือตำแหน่ง (Address) ที่อยู่ในหน่วยความจำของคอมพิวเตอร์ ซึ่งจะใช้สำหรับกำหนดค่าหรือเข้าถึงข้อมูล พอยเตอร์นั้นสร้างจากแนวความคิดพื้นฐานของ Pointer Constants

Pointer Values

          Pointer Values คือ ค่าตำแหน่ง Address ของตัวแปรนั้น ถ้าต้องการค่าของ Address ของตำแหน่งของตัวแปรใด หรือจะ กำหนดค่าที่รับเข้ามาทางคีย์บอร์ดให้ไปเก็บไว้ที่ตัวแปรนั้นจะต้องใช้ดเครื่องหมาย Address หรือ & ดังตัวอย่างด้านล่างแสดงการ ใช้ตัวแปร aCha
          &aChar

 

 

 

 

 

 

 

 

ตัวแปรพอยเตอร์


          ถ้าผู้ใช้มี Pointer Constant และ Pointer Value ผู้ใช้ก็สามารถมี Pointer Variable หรือตัวแปรพอยเตอร์ได้ และผู้ใช้ก็สามารถบรรจุ Address ของตัวแปรตัวหนึ่งให้กับตัวแปรอีกตัวหนึ่งได้ ซึ่งแสดงในรูปที่ 9-2

 

 

 

 

 

 

 

 

 

           ผู้ใช้จะต้องแบ่งระหว่างตัวแปรกับค่าของมัน รูปที่ 9-2 แสดงรายละเอียดที่แตกต่างกันในรูปแสดงให้เห็นว่า ตัวแปร
a มีค่า –123 และตัวแปร a นั้นตั้งอยู่ในตำแหน่งที่ 234560 ในหน่วยความจำ แม้ว่าชื่อขงองตัวแปรแบะตำแหน่งจะเป็นค่าคงที่ แต่ค่าเหล่านั้นก็สามารถเปลี่ยนแปลงได้ เมื่อโปรแกรมทำไปแล้ว ในรูปนี้มีตัวแปรพอยเตอร์ p อยู่ด้วยพอยเตอร์ จะมีชื่อและ ตำแหน่งอยู่ด้วย ซึ่งทั้งคู่ก็เป็นค่าคงที่ด้วยเช่นกัน ค่าของมันในตำแหน่งนี้คือ ตำแหน่งของหน่วยความจำที่ 234560 ความหมายคือ p ชี้ไปยังตำแหน่งที่ a อยู่ในรูปที่ 9-2 ลักษณะทางกายภาพได้แสดงถึวข้อมูลและตัวแปรพอยเตอร์ที่อยู๋ในหน่วยความจำ ส่วนใน ลักษณะทางความคิดแสดงให้เห็นความสัมพันธ์ระหว่างสิ่งเหล่านั้น

           ผู้ใช้สามารถที่กำหนดตำแหน่ง Address ของตัวแปรให้กับตัวแปรพอยเตอร์ได้มากกว่าหนึ่งตัว ซึ่งแสดงตัวอย่างในรูปที่ 9-3 ในรูปนี้จะมีตัวแปร a และตัวแปรพอยเตอร์ p และ q ซึ่งแต่ละพอยเตอร์ทั้งสองจะมีชื่อและตำแหน่งที่เป็นค่าคงที่ และทั้งคู่มีค่าที่ชี้ไป ยังตำแหน่งหน่วยความจำที่ 234560 หมายความว่าทั้ง p และ q ชี้ไปยังที่ตัวแปร a และตัวแปรพอยเตอร์ที่จะชี้ไปยังตำแหน่ง Address ของตัวแปรตัวเดียวกันนั้นสามารถมีได้ไม่จำกัดจำนวน

 

 

 

 

 

 

 

 

 

การเข้าถึงตัวแปรพอยเตอร์

          ในขณะนี้ผู้ใช้มีตัวแปรและมีพอยเตอร์ที่ชี้ไปยังตัวแปรตัวนั้น เมื่อไรที่ผู้ใช้ต้องการพอยเตอร์และต้องการเข้าถึงค่าที่พอยเตอร์ตัวนั้นชี้อยู่ จะต้องใช้ตัวดำเนินการ Indirection หรือ * ยกตัวอย่างเช่น ถ้าต้องการเข้าถึงค่าของตัวแปรที่มีพอยเตอร์ p ชี้อยู่ ก็สามารถเขียนได้ดังนี้

             *p

           อีกตัวอย่างหนึ่ง ถ้าผู้ใช้ต้องการที่จะบวก 1 ให้กับตัวแปร a ผู้ใช้สามารถทำได้ อย่างเช่นใช้ชุดคำสั่งปกติ หรือสมมุติว่ามีพอยเตอร์ p และกำหนดให้ p = &a จะเขียนชุดคำสั่งได้ดังนี้

               a++; a=a+1; *p=p+1; (*p)++;

          ในตัวอย่างชุดท้าย (*p)++ ผู้ใช้ต้องใช้วงเล็บตามตัวอย่าง ไม่เช่นนั้นโปรแกรมจะผิดพลาดขึ้นมาทันที เพราะนิพจน์แบบ Postfix แบบเพิ่มค่า มีลำดับความสำคัญอยู่ที่ 16 แต่เครื่องหมาย * มีลำดับความสำคัญอยู่ที่ 15 ฉะนั้นการทำงานโดยไม่ใส่วงเล็บจะเป้ฯการเพิ่มค่าของตำแหน่งที่อยู่ที่ p เก็บอยู่ไปอีก 1 ก่อน แล้วจึงไปนำค่าในตำแหน่งที่อยู่ใหม่ออกมาแทน

         รูปที่ 9-4 จะแสดงตัวอย่างการเข้าถึงต่างๆ ซึ่งมีตัวแปร x และมีตัวแปรพอยเตอร์ p และ q ที่ชี้ไปยังตัวแปร a

 

 

 

 

 

 

 

 

 

 

 

 

 

 

          เครื่องหมาย Indirection (*) และ address(&) จะเป็นเครื่องหมายที่มีความหามายตรงกันข้าม และเมื่อนำมารวมกัน เช่น *&x ก็จะมีความหมายเท่ากับ x นั่นเอง

 

 

 

 

 

การประกาศและกำหนดลักษณะของพอยเตอร์

          รูปที่ 9-6 ผู้ใช้จะใช้เครื่องหมาย Indirection ในการประกาศและกำหนดลักษณะของตัวแปรพอยเตอร์ เมื่อทำตามนี้แล้วพอยเตอร์ก็จะยังไม่ชี้ไปยังตัวแปรใด จะทำการกำหนดค่าให้ก่อนเสมอเหมือนตัวแปรทั่วๆไป

 

 

 

 

 

           ในรูปที่ 9-7 แสดงการประกาศตัวแปรพอยเตอร์แบบต่างๆ ซึ่งจะมีข้อมูลที่ตรงตามชนิดข้อมูล และพอยเตอร์ ์ที่ประกาศจะมี ชนิดข้อมูลเป็นดังนี้ p เป็นพอยเตอร์ชนิดตัวอักษร (Character),q เป็นพอยเตอร์ชนิดตัวเลขจำนวนเต็ม (Integer) และ r เป็นพอยเตอร์ชนิดตัวเลขทศนิยม (Floating – point)

 

 

 

 

 

 

 

 

 

 

 

 

         ในโปรแกรมที่ 9-1 เป็นการบรรจุ Address ของตัวแปรให้กับพอยเตอร์ และพิมพ์คำเหล่านั้นออกมาโดยใช้ทั้งตัวแปร และพอยเตอร์

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

การกำหนดค่าเริ่มต้นของพอยเตอร์

          ในภาษา C ถ้าไม่มีการกำหนดค่าเริ่มต้นให้กับตัวแปร เหมือนโปรแกรมเริ่มทำงานหน่วยความจำ ของตัวแปรนั้นจะ มีค่า บางอย่าง ที่ไม่อาจจะทราบได้

           พอยเตอร์ก็เหมือนกับตัวแปร คือ เมื่อโปรแกรมเริ่มทำงานแล้ว ไม่ได้ทำการกำหนดค่าเริ่มต้นให้กับพอยเตอร์ ในหน่วย ความจำของพอยเตอร์ตัวนั้นจะมีค่าบางอย่างที่ไม่อาจจะทราบได้ค่าบางอย่างนั้นคอมพิวเตอร์อาจจะนำไปใช้ไม่ได้ และถ้านำไปใช้ อาจจะทำให้โปรแกรมเกิดการผิดพลาดขึ้นได้ ดังรูปที่ 9-8 จะแสดงตัวแปรและพอยเตอร์ที่ไม่มีการกำหนดค่า

 

 

 

 

 

 

 

 

 

 

               ปัญหาที่แสดงในรูปที่ 9-8 คือ ผู้ใช้ทำการกำหนดค่าให้ตัวแปรหรือพอยเตอร์เหล่านั้น เช่น

                   int x;                                                     /* ตัวแปรชนิด int*/

                int p=&a;                                            /*p มีค่าของ Address*/

                p=89                                                      /* กำหนดค่า 89 ให้ a*/

จากตัวอย่างด้านบนในบรรทัดที่ 2 จะพบว่า มีการทำ 2 คำสั่งในบรรทัดเดียวกัน ซึ่งคำสั่งแสดงในรูปที่ 9-9

 

 

 

 

 

 

 

 

              และถ้าต้องการให้พอยเตอร์ชี้ไปที่ค่า NULL ก็สามารถทำได้ดังนี้

Int*p=NULL

             เมื่อได้กำหนดพอยเตอร์ให้เป็น NULL ก็เท่ากับผู้ใช้ได้ใช้ Address ที่ 0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

            ในโปรแกรมที่ 9-3 นี้จะเป็นการใช้พอยเตอร์ในการบวกเลขสองตัว ซึ่งจะมีตัวแปรต่างๆ ดังรูปที่ 9-10

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

พอยเตอร์กับฟังก์ชัน

          ในการใช้พอยเตอร์กับฟังก์ชัน จะมีการใช้อยู่ 2 แบบ คือ

          1. การใช้พอยเตอร์เป็นพารามิเตอร์ (Pointer ass Formal Parameters) รูปที่ 9-11 และ 9-12 เป็นการสาธิตการใช้พอยเตอร์ ในรูปที่ 9-12 นั้น มีการเรียกใช้ฟังก์ชัน Exchange ซึ่งฟังก์ชัน Exchange นี้ต้องการตัวแปร 2 ตัว ส่งไปให้เมื่อผู้ใช้ใช้การส่งค่าแบบ Pass-by-value ข้อมูลที่แท้จริงในฟังกืชันทีเรียกจะไม่ถูกเปลี่ยนในฟังก์ชันที่ถูกเรียก

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

          ถ้าต้องการจะให้ค่าของตัวแปรตัวจริงสลับกัน จะต้องใช้พอยเตอร์เข้ามาช่วย หรือไม่ก็ประกาศตัวแปรเหล่านั้นแบบ Global

         ในรูปที่ 9-12 แสดงการสลับค่าโดยใช้พอยเตอร์ให้สร้างพอยเตอร์ขึ้นมา แล้วเครื่องหมาย Address ในเวลาที่ส่งค่าไปให้กับฟังก์ชั่นอื่น ซึ่งแสดงดังตัวอย่างข้างล่าง จะส่งค่าตำแหน่ง Address ของตัวแปร a และ b ไปให้

                exchange(&a,&b);

          ในการใช้การส่งค่าโดย Address นี้ พารามิเตอร์ในฟังก็ชั่นที่ถูกเรียก จะต้องกำหนดเป็นตัวแปรพอยเตอร์ ดังตัวอย่าง ที่แสดงด้านล่าง
          void exchange(int *x,int *y);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

            2. ฟังก์ชันที่มีการส่งค่ากลับเป็นพอยเตอร์ (Functions Returning Parameters) ถ้าผู้ใช้มีฟังก์ชันที่ ใช้หาค่าที่น้อยที่สุดระหว่างตัวเลข 2 ตัว ในกรณีนี้ผู้ใช้จะต้องกำหนดให้พอยเตอร์ที่ชี้ไปตัวแปรทั้ง 2 ตัวนั้น โดยให้เป็น a และ b โดยในฟังก์ชันมีเงื่อนไขที่ใช้หาค่าที่น้อยกว่า และถ้าตัวเลขตัวไหนน้อยกว่าก็ส่งค่า Address ของตัวเลขตัวนั้นกลับมา ตัวอย่าง การส่งค่ากลับโดยใช้พอยเตอร์ แสดงในรูปที่ 9-13

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Pointers To Pointers

          Pointers To Pointers คือ การใช้พอยเตอร์ตัวหนึ่งชี้ไปยังพอยเตอร์อีกตัวหนึ่ง ซึ่งพอยเตอร์นั้นชี้ไปยังตัวแปร ซึ่งในรูปที่ 9-14 แสดงการชี้ 2 ระดับ ซึ่งการทำแบบนี้สามารถทำได้ไม่จำกัดระดับ

         ในแต่ละระดับนั้นต้องมีเครื่องหมาย Indirection 1 ตัว ดังรูปที่ 9-17 ให้ p ชี้ไปยัง a ก็สามารถ เขียนคำสั่งได้ดังนี้

           *P

       และถ้าต้องการให้ q ชี้ไปยัง a โดยผ่าน p ก็จะเป็น 2 ระดับ ก็จะเขียนคำสั่งได้ดังนี้

                **q

         ซึ่งผลลัพธ์ของโปรแกรมที่แสดงในรูปที่ 9-17 จะได้ดังนี้

          58 58 58

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

              ในโปรแกรมที่ 9-4 แสดงการใช้ Pointers To Pointers ซึ่งจะโปรแกรมตามรูปที่ 9-15