พอยน์เตอร์,การจองหน่วยความจำ (C/C++)


#include <stdio.h>#include <conio.h>
int main( )
{
int *pointer1; //<----- วิธีกำหนดตัวแปร พอยน์เตอร์
int value1 = 10; //<---- กำหนดตัวแปรแบบ Integer ให้ค่า 10
pointer1 = &value1; //<--- ให้ pointer ชี้ไปยังตำแหน่งของ value1 ที่เก็บค่า 10
printf( "%i", value1 ); //<--- พิมพ์ค่า value1
printf( "%i", (int)(*pointer1) ); //<--- พิมพ์ค่าที่ชี้ไปยังตำแหน่งนั้น
return 0;
}

1010

. . . . . . . .จากตัวอย่างข้างบนมันทำงานดังนี้ครับ การกำหนดตัวแปรแบบ pointer ต้องมีเครื่องหมายดอกจัน นำหน้าตัวแปรนั้น และวิธีการชี้ไปยังตำแหน่งที่ต้องการ ให้ทำแบบนี้
pointer1 = &value1; //<--- ให้ pointer ชี้ไปยังตำแหน่งของ value1 ที่เก็บค่า 10
เครื่องหมาย & คือบอกว่าตัวแปรนั้นอยู่ตำแหน่งใดในหน่วยความจำ แต่การให้ค่า pointer1 ต้องใช้แบบนี้
*pointer1 = 10; //<--- ให้ค่า pointer1 ไม่ใช่การให้ตำแหน่งที่อ้างถึง
จากข้างบนเมื่อเราให้ค่า *pointer1 = 10 ตัวแปร value1 ก็จะมีค่าเท่ากับ 10 เหมือนกัน เพราะว่าเราอ้างถึงตำแหน่ง ที่เก็บค่าสิบตัวเดียวกัน ก็ง่ายๆ ว่า ตัวแปร pointer มีหน้าที่ชี้ตำแหน่งแค่นั้นเอง และเราสามารถแก้ไข ตำแหน่งนั้นได้เลย เพราะมันเป็นที่เดียวกัน ประโยชน์ของมันมีมากเลยละ และการใช้ค่าที่พอยน์เตอร์ชี้ไปนั้น ต้องกำหนดรูปแบบให้มันด้วยว่าเป็นข้อมูลแบบไหน เช่น

#include <stdio.h>#include <conio.h>
#include <string.h>
int main( )
{
int *pointer1; //<----- วิธีกำหนดตัวแปร พอยน์เตอร์
int value1 = 10; //<---- กำหนดตัวแปรแบบ Integer ให้ค่า 10
int value2 = 20; //<---- กำหนดตัวแปรแบบ Integer ให้ค่า 20
pointer1 = &value1; //<--- ให้ pointer ชี้ไปยังตำแหน่งของ value1 ที่เก็บค่า 10
printf( "%i", value1 ); //<--- พิมพ์ค่า value1
printf( "%i", (int)(*pointer1) ); //<--- พิมพ์ค่าที่ชี้ไปยังตำแหน่งนั้น
pointer1 = &value2; //<--- ให้ pointer ชี้ไปยังตำแหน่งของ value1 ที่เก็บค่า 10
printf( "%i", (int)(*pointer1) ); //<--- พิมพ์ค่าที่ชี้ไปยังตำแหน่งนั้น
return 0;
}

1010
20

. . . . . . . .ใครกำลังงง ลองดูตัวอย่างซ้ำๆ นะครับ เพราะเห็นแล้วจะอ๋อ.........จากตัวอย่างข้างบน pointer ตัวเดียวแต่อ้างตำแหน่งข้อมูลได้ 2 ที่ แบบนี้
pointer1 = &value1; //<--- ให้ pointer ชี้ไปยังตำแหน่งของ value1 ที่เก็บค่า 10
เมื่อพิมพ์ค่าที่ pointer1 ชี้ไปก็จะพิมพ์ค่า 10 ออกมาและ
pointer1 = &value2; //<--- ให้ pointer ชี้ไปยังตำแหน่งของ value1 ที่เก็บค่า 20
เมื่อพิมพ์ค่าที่ pointer1 ชี้ไปก็จะพิมพ์ค่า 20 ออกมา ก็แค่การอ้างถึงตำแหน่งข้อมูลเฉยๆ ไม่ยากๆ สามารถกำหนดตัวแปร pointer ได้หลายแบบลองดูนะครับ
printf( "%i", (int)(*pointer1) ); //<--- พิมพ์ค่าที่ชี้ไปยังตำแหน่งนั้น เป็น Interger
printf( "%i", (long)(*pointer1) ); //<--- พิมพ์ค่าที่ชี้ไปยังตำแหน่งนั้น เป็น long
อย่าใช้ผิดแบบ คือชี้ไม่ถูกตัวแปรละครับ ไม่งั้นโปรแกรมจะทำงานผิดพลาดครับ

การจองหน่วยความจำ


. . . . . . . .การใช้งานพอยน์เตอร์ เป็นแค่ตำแหน่งเฉยๆ แต่ไม่มีพื้นที่ใช้งาน เราต้องจองพื้นที่ใช้งาน สำหรับเก็บข้อมูล และเราก็ต้องยกเลิกเมื่อไม่ใช้งานแล้ว ดังตัวอย่างต่อไปนี้

#include <stdio.h>#include <conio.h>
#include <string.h>
#include <malloc.h>
int main( )
char *data = (char *)malloc( 20 ); //<----- จองพื้นที่ใช้งาน
strcpy( data, "Sawasdee" );
printf( "%s\n", data );
free( data ); //<----- ยกเลิกพื้นที่ที่จอง
return 0;
}

Sawasdee

. . . . . . . .จากข้างบนเราเรียก function malloc สำหรับจองพื้นที่ใช้งาน อันเนื่องมาจากว่า ตัวแปรพอนต์เตอร์มีขนาดแค่ 4 ตัวอักษร มีหน้าที ชี้ไปยังตำแหน่งที่ต้องการเท่านั้นเอง เราจึงต้องจองพื้นที่ใช้งาน มาก่อนแล้วให้ตัวแปรพอนต์ชี้ไป แล้วถึงจะใช้งานได้ และหลังจากใช้งานเสร็จเราก็ยกเลิก หน่วยความจำนั้นทันทีโดยใช้ function free ไม่น่ายากอะไรดูข้างบนอีกครั้งนะครับ และถ้าเป็นการเขียนแบบ C++ เราสามารถเขียนได้แบบนี้ ดูตัวอย่าง

#include <stdio.h>#include <conio.h>
#include <string.h>
int main( )
{
char *data = new char[ 20 ];
strcpy( data, "Sawasdee" );
printf( "%s\n", data );
delete data;
return 0;
}

Sawasdee

. . . . . . . .จากข้างบนเราเรียก function new สำหรับจองพื้นที่ใช้งาน และยกเลิกด้วย function delete แต่การทำงานเหมือนกันครับ ไม่ยากเลยใช่ไหม ลองดูอีกแบบนะครับ

#include <stdio.h>#include <conio.h>
#include <string.h>
#include <malloc.h>
int main( )
{
intr *data = (int *)malloc( 3 );
data[0] = 10;
data[1] = 20;
data[2] = 30;
printf( "%i %i %i\n", data[0], data[1], data[2] ); //<--- ใช้เหมือน array
free( data );
return 0;
}

10 20 30

. . . . . . . .จากข้างบนเราเมื่อเราจองพื้นที่ทำงานแล้ว เราสามารถอ้างได้เหมือน array เลย ดูดี ดีสิ สำคัญจองไปไว้เท่าไรอย่าใช้เกินนะครับ จุดเริ่มต้นใช้งานให้นับจาก 0 นะครับ อย่าลืมๆ ต่อไปเป็นการจองพื้นที่ให้กับตัวแปรโครงสร้าง ก็ไม่มีอะไรมาก ลองดู

#include <stdio.h>#include <conio.h>
#include <string.h>
#include <malloc.h>
typedef struct TRecord
{
char data[80];
};
int main( )
{
struct TRecord *rec1 = (struct TRecord *)mallocsizeof( TRecord );//<-- จองพื้นที่ใช้งาน
strcpy( rec1 -> data, "Sawasdee" ); //<--- ให้ค่าฟิลด์
printf( "%s", rec1 -> data );
free( rec1 ); //<--- ยกเลิกพิ้นที่ใช้งาน
return 0;
}

Sawasdee

. . . . . . . .วิธีใช้ function malloc ให้ใส่จำนวนพื้นที่ที่ต้องการ ขนาดเป็น 1 ตัวอักษร แต่เราใช้ function sizeof เข้ามาช่วยคำนวณขนาดของ TRecord หลังจากนั้นให้ค่าตำแหน่งที่จองได้แก่ พอยน์เตอร์ rec1 และการเข้าถึงฟิลด์ในโครงสร้างต้องใช้เครื่องหมาย -> ไม่ใช่จุดไข่ปลานะครับ อย่าลืมๆ หลังจากนั้นยกเลิกด้วย function free มาดูตัวอย่างที่เขียนด้วย C++ กันบ้าง

#include <stdio.h>#include <conio.h>
#include <string.h>
#include <malloc.h>
struct TRecord
{
char data[80];
};
int main( )
{
TRecord *rec1 = new TRecord;
strcpy( rec1 -> data, "Sawasdee" ); //<--- ให้ค่าฟิลด์
printf( "%s", rec1 -> data );
delete rec1;
return 0;
}

Sawasdee

. . . . . . . .นี่คือข้อดีของ C++ จะเห็นว่า จะสั้นกว่า C ธรรมดามาก แต่ทำงานเหมือนกัน ลองเปรียบเทียบดูนะครับ

สรุป ได้อะไรบ้าง


int *pointer1; //<----- วิธีกำหนดตัวแปร พอยน์เตอร์pointer1 = &value1; //<--- ให้ pointer ชี้ไปยังตำแหน่งของ value1 ที่เก็บค่า 10
intr *data = (int *)malloc( 3 );
data[0] = 10;
data[1] = 20;
data[2] = 30;
printf( "%i %i %i\n", data[0], data[1], data[2] ); //<--- ใช้เหมือน array
char *data = (char *)malloc( 20 ); //<----- จองพื้นที่ใช้งาน
free( data ); //<-- ยกเลิกพื้นที่ใช้งาน
char *data = new char[ 20 ];
delete data; //<-- ยกเลิกพื้นที่ใช้งาน
struct TRecord *rec1 = (struct TRecord *)mallocsizeof( TRecord ); //<-- จองพื้นที่ใช้งาน
strcpy( rec1 -> data, "Sawasdee" ); //<--- ให้ค่าฟิลด์
printf( "%s", rec1 -> data );
free( rec1 ); //<--- ยกเลิกพิ้นที่ใช้งาน
TRecord *rec1 = new TRecord;
delete rec1;

. . . . . . . .วันนี้ออกจะสั้นเพราะเป็นเนื้อหาที่ไม่ซับซ้อนมากนัก แต่ควรจะลองเขียนบ่อยๆ เพราะไม่ยากเกินไปสำหรับเรา แต่เป็นพื้นฐานที่ควรรู้สำหรับโปรแกรมเมอร์ หมั่นเขียนบ่อยๆ ขยัน อดทน เพราะต่อไปเป็นการเขียนกราฟฟิกแล้วครับ