พอยน์เตอร์
พอนย์เตอร์ คืออะไร
พอนย์เตอร์ (pointer) คือตัวแปรที่เก็บค่าของที่อยู่ของข้อมูลของตัวแปร การใช้พอนย์เตอร์จะทำให้เราสามารถเข้าถึงข้อมูลได้โดยตรงโดยใช้ที่อยู่ของหน่วยความจำ แทนที่จะใช้ชื่อของตัวแปรที่เราได้ใช้ในบทก่อนหน้านี้ พอนย์เตอร์มีประโยนช์สำหรับ low-level programming เช่นการเขียนโปรแกรมในภาษา C
พอนย์เตอร์ ในภาษา C
ในภาษา C เราสามารถเขียนโปรแกรมโดยการใช้พอยน์เตอร์ได้ ซึ่งเราจะกล่าวว่าพอนย์เตอร์จัดเป็นตัวแปรชนิดของมันเอง แต่หลักการทำงานนั้นคล้ายคลึงกับตัวแปรทั่วไป มีเครื่องหมายที่สำคัญที่คุณต้องรู้เกี่ยวกับพอนย์เตอร์
- Address-of operator (&)
- Dereference operator (*)
- Declaration operator (*)
Address-of operator (&)
การใส่สัญลักษณ์ ampersand (&) หน้าตัวแปรนั้นจะทำให้เราได้รับค่าที่อยู่ของตัวแปรในหน่วยความจำ ที่อยู่นี้สามารถได้รับมาได้ในตอนที่โปรแกรมรันเท่านั้น ซึ่งมันจะบอกว่าตัวแปรที่เก็บอยู่ที่ตำแหน่งไหนของหน่วยความจำ ยกตัวอย่างเช่น
&myVariable;
การใช้คำสั่งนี้ เราจะได้ค่าที่อยู่ของตัวแปร myVariable
โดยค่าที่อยู่นั้นจะอยู่ในเลขฐานสิบหก เนื่องจากที่อยู่ของหน่วยความจำนั้นจำเป็นต้องรันโปรแกรม โดยปกติแล้วที่อยู่ของหน่วยความจำจะแสดงในเลขฐาน 16 ในบทเรียนนี้เราจะใช้ฐาน 10 เพื่อให้ง่ายต่อการเข้าใจ
int myVariable = 8;
printf("%d", &myVariable); // 1367
ในตัวอย่างด้านบน โปรแกรมจะแสดง 1367 ออกทางหน้าจอ นั่นหมายความว่าตัวแปร myVariable
ถูกเก็บอยู่ที่ตำแหน่ง 1367 ในหน่วยความจำ ดังนั้นเราสามารถใช้ค่าที่อยู่นี้ในการถึงค่าของตัวแปร myVariable
ได้โดยตรง โดยปกติเราจะใช้ %x
เพื่อแสดงผลค่าที่อยู่ในเลขฐาน 16
Dereference operator (*)
ในตัวอย่างก่อนหน้า ที่อยู่ของตัวแปรนั้นสามารถได้มาโดยการใส่เครื่องหมาย ampersand (&) หน้าตัวแปร ในการเข้าถึงข้อมูลของตัวแปรพอนย์เตอร์ เราใช้จะใช้เครื่องหมาย star *
หน้าตัวแปรพอยน์เตอร์เพื่อเข้าถึงข้อมูลในที่อยู่ของพอยน์เตอร์
int myVariable = 8;
int *myPointer = &myVariable; // ประกาศตัวแปรพอนย์เตอร์
printf("%d", *myPointer); // เข้าถึงข้อมูลของตัวแปรพอนย์เตอร์
ในตัวอย่างตัวแปร myPointer
ถูกประกาศโดยใช้คำสั่ง *myPointer
ในตรงนี้โปรดอย่าสับสนกับการเข้าถึงข้อมูลของตัวแปรที่คุณเห็นในฟังก์ชัน printf("%d", *myPointer)
ซึ่งเป็นการเข้าถึงข้อมูลของตัวแปร myPointer
Declaring pointers
หลังอยากที่ได้รู้จักพอยน์เตอร์แล้ว ต่อไปจะเป็นการประกาศตัวแปรพอยน์เตอร์เพื่อใช้งาน ในการประกาศตัวแปรพอนย์เตอร์ เราจะใช้เครื่องหมาย star (*) เช่นเดียวกับการเข้าถึงค่าของตัวแปร ดังนั้นโปรดอย่าสับสนในตรงนี้ มาดูตัวอย่างในการประกาศตัวแปร
#include <stdio.h>
int main()
{
int number = 10;
float money = 34.8;
int *p1 = &number;
float *p2;
p2 = &money;
printf("p1 address = %x\n", p1);
printf("p1 value = %d\n", *p1);
printf("p2 address = %x\n", p2);
printf("p2 value = %f\n", *p2);
return 0;
}
ในตัวอย่างเราได้ประกาศตัวแปร 2 ตัว คือ number
ซึ่งมีประเภทเป็น integer และ money
ซึ่งมีประเภทเป็น float ต่อมาเราประกาศตัวแปรพอยน์เตอร์ p1
และ p2
สังเกตุว่าเราใส่เครื่องหมาย *p1
นำหน้าชื่อของตัวแปร และประเภทของตัวแปรต้องตรงกับตัวแปรที่จะใช้เก็บตำแหน่งที่อยู่ เช่น int *p1
จะใช้เก็บที่อยู่ของตัวแปร number
หลังจากนั้นเราแสดงค่าที่อยู่ของตัวแปรพอยน์เตอร์และค่าที่ตัวแปรพอยน์นั้นชี้อยู่ ในการแสดงค่าที่อยู่ เราไม่ต้องใช้เครื่องหมาย &
เพราะ p1 และ p2 เป็นตัวแปรพอยน์เตอร์แล้ว
และนี่เป็นผลลัพธ์เมื่อโปรแกรมรัน
p1 address = 28ff04
p1 value = 10
p2 address = 28ff00
p2 value = 34.799999
การใช้พอนย์เตอร์กับอาเรย์
การใช้พอยน์เตอร์กับอาเรย์นั้นมีประโยชน์ เพราะอาเรย์เป็นการเก็บข้อมูลแบบชุดอันดับ และเรียงต่อกัน
#include <stdio.h>
int main()
{
int number[5] = {10, 20, 30, 40, 50};
int *myPointer = &number;
printf("first -> %d\n", *myPointer);
myPointer++;
printf("go next -> %d\n", *myPointer);
myPointer += 3;
printf("go next 3 -> %d\n", *myPointer);
myPointer--;
printf("go back -> %d\n", *myPointer);
return 0;
}
ในตัวอย่าง ในการใช้พอนย์เตอร์กับตัวแปรอาเรย์ จะได้ค่าตัวแหน่งแรกของอาเรย์เสมอ ดังนั้นเราสามารถไปที่ตำแหน่งต่างของอาเรย์ได้ เช่น ไปตำแหน่งถัดไปเราใช้ myPointer++
และตำแหน่งก่อนหน้าเราใช้ myPointer--
ไปตำแหน่งที่ต้องการเราจะใช้ myPointer += n
ดังในตัวอย่างจะได้ผลลัพธ์ดังนี้
first -> 10
go next -> 20
go next 3 -> 50
go back -> 40
Pointer arithmetics
พอนย์เตอร์เป็นตัวแปร ดังนั้นเราสามารถใช้การดำเนินการทางคณิตศาสตร์กับพอยน์เตอร์เช่นเดียวกับตัวแปรได้ แต่สำหรับพอยน์เตอร์แล้วจะเป็นการทำงานกับที่อยู่ของหน่วยความจำแทน ยกตัวอย่างเช่น
int *p1 = &foo; // 1367;
p1 += 1000; // 2367
p1++; // 2368
// work with arrays
int a[400];
int *p2 = &a;
p2 += 399;
*p2 = 1234;
ในตัวอย่างสมมติเรามีตัวแปรพอยน์เตอร์ p1
เก็บค่าที่อยู่ที่ 1367 เราสามารถไปที่ตำแหน่งที่อยู่ 2367 ในหน่วยความจำได้โดยบวก 1000 ให้กับตัวแปร ในตัวอย่างที่สองเราใช้กับอาเรย์ โดยการไปที่ตำแหน่งสุดท้ายของอาเรย์และกำหนดค่า 1234 ให้กับอาเรย์ที่ตำแหน่ง a[399]
ในบทนี้ เราได้ครอบคลุมเนื้อหาการใช้งานพอนย์เตอร์ในพื้นฐาน