วันพฤหัสบดีที่ 15 เมษายน พ.ศ. 2553

Pointer กับ Array

pointer กับ array ในภาษา c++ จะมีความใกล้ชิดกันมาก ตัวอย่างเช่น เมื่อประกาศตัวแปรarray ชนิดหนึ่งขึ้นมา ชื่อตัวแปรนั้น ก็คือ address ที่ชี้ไปยังดัชนีแรกสุด โดยที่เราไม่ต้องใช้ operator & วางหน้าตัวแปรarray เลย และถ้าเราเพิ่มจากเดิมไปอีก1ก็จะได้เป็น address ใหม่ที่จะชี้ตำแหน่งถัดไป ลองมาดูตัวอย่างกันคับ

int x[5] = {12,14,16,18,20};

cout<<x<<endl; //พิมพ์ค่า address ของ array ณ ตำแหน่งที่ 0 ออกมา

cout<<x+1<<endl; //เพิ่มค่าindexเข้าไปอีก1 จะทำให้ address เพิ่มไปอีก 1 ตำแหน่ง

วันอังคารที่ 13 เมษายน พ.ศ. 2553

Decimal to Binary

#include <iostream>

#include <string>

using namespace std;

string compute(int n){

     if(n==0)

          return "";

     else if(n%2==0)

          return compute(n/2)+"0";

     else

          return compute(n/2)+"1";

}

int main(){

     cout<<compute(14)<<endl;

     return 0;

}

วันพุธที่ 7 เมษายน พ.ศ. 2553

Binary to Decimal

#include <iostream>

#include <string>

using namespace std;

int compute(string s){

     if(s=="")

          return 0;

     else if(s.at(s.length()-1)=='1')

          return compute(s.erase(s.length()-1,1))*2+1;

     else

          return compute(s.erese(s.length()-1.1))*2+0;

}

int main(){

     cout<<compute("1110010")<<endl;

     return 0;

}

วันจันทร์ที่ 5 เมษายน พ.ศ. 2553

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

เราจะจองหน่วยความจำเมื่อเราต้องการให้Programของเราทำงานแบบ Dynamic แต่ถ้าเรากำหนดขนาดของตัวแปรแบบArrayเอาไว้ล่วงหน้าแล้ว ถ้าเวลาจริงเราใช้ไม่พอ ก็จะขยายขนาดของArrayไม่ได้เลย จึงต้องหันไปใช้ LinkedList แทน การจองพื้นที่หน่วยความจำใน c และ c++ ก็จะต่างกันหน่อยนึง ลองมาดูกันคับ

  • ภาษา c จะใช้ function พวก malloc,calloc ในการจองหน่วยความจำและใช้คำสั่ง free ในการคืนหน่วยความจำให้กับระบบ
  • ภาษา c++ จะใช้คำสั่ง new ในการจองหน่วยความจำ และ delete ในการคืนหน่วยความจำให้กับระบบ

เราลองมาดูตัวอย่างกันนะคับ

int *num;

*num = 72;

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

int *num;

num = new int;

*num=72;

cout<<*num<<endl;

delete num;

เมื่อเราจองหน่วยความจำได้แล้ว ข้อมูลในช่องนั้นสามารถนำไปใช้ในโปรแกรมของเราได้ ส่วนมากในการเขียนโปรแกรมทั่วๆไป เราไม่จำเป็นต้องประกาศตัวแปรPointer และจองหน่วยความจำแบบนี้เสมอไป เราก็แค่ประกาศตัวแปรแบบธรรมดาและเก็้บค่าไปเท่านั้น แต่ในการทำงานของ LinkedList นั้นจะต่างจาก array ตรงที่ linked list ไม่ได้จองหน่วยความจำทีเดียวแบบ array เช่น

int number[40];

array number ตัวนี้จะเเก็บค่าได้ 40 ตัว ขยายก็ไม่ได้ด้วย แต่ถ้าเราเปลี่ยนมาให้ LinkedList เราจะต้องจองหน่วยความจำให้กับข้อมูลที่ต้องการจะเก็บ และถ้าจะเพิ่มข้อมูลเข้าไปใน Linked List อีก ก็จองหน่วยความจำให้กับข้อมูลใหม่ และก็เชื่อมต่อเข้าไปอีกเรื่อยๆ

วิธีการของ Linked List นี้จะข่วยไม่ให้เราต้องจองหน่วยความจำเอาไว้มากมาย และจะเก็บข้อมูลเท่าที่เราต้องการจะเก็บเท่านั้น เมื่อเราลบข้อมูลในช่องใดออกไปก็จะไม่มีช่องว่างเหลือเหมือนกับarray

วันอาทิตย์ที่ 4 เมษายน พ.ศ. 2553

Pointer to Structures

การใช้ pointer ชี้ไปที่ข้อมูลชนิด structure เป็นที่นิยมมาก โดยเราจะใช้ตัวดำเนินการ -> (arrow operator) ในการอ้างถึงฟิลด์ต่างๆ เราลองมาพิจารณาโครงสร้างชนิดข้อมูลนี้กันดูคับ

struct database {

     int key;

     int big_array[25];

}my_data;

เป็นการประกาศข้อมูลชนิดโครงสร้างโดยใช้ชื่อ database แล้วก็กำหนดให้ my_data เป็นตัวแปรชนิดนี้ แล้วก็จะประกาศ pointer ชื่อ my_pointer ให้เป็นตัวแปร pointer ชนิดโครงสร้างนี้

struct database *my_pointer;

เราสามารถกำหนดให้ pointer ชื่อ my_pointer ชื่อไปยังตัวแปร my_data ได้ดังนี้

my_pointer = &my_data;

ต่อจากนี้เราก็จะสามารถอ้างถึงฟิลด์ต่างๆใน my_data เช่น my_data.key โดยใช้ตัวดำเนินการ ->

my_pointer -> key = 5;   // ใช้เช่นเดียวกับ my_data.key

วันเสาร์ที่ 3 เมษายน พ.ศ. 2553

Pointers to Pointers

Pointer ชี้ไปที่ Pointer ต่างๆ

ใน c เราสามารถกำหนดตัวแปรpointerให้ชี้ไปยังตัวแปรpointerตัวอื่นๆได้อีก การกำหนดให้ pointer ชี้ไปยัง pointer อื่นๆใน C จะใช้เครื่องหมาย ** ข้างหน้าตัวแปร เพื่อระบุ pointer ชี้ไปยัง pointer เช่น

char **char_ptr;

จำนวนของ * ทั้งหมดที่เขียนไว้ข้างหน้าตัวแปรเพื่ออ้างอิงค่าที่pointerชื้ เรียกว่า Level of indirection ของตัวแปร pointer เพื่อใช้ระบุจำนวนตัวแปรpointerที่ชี้ต่อเนื่องกันไปจนถึงแหล่งข้อมูล

ตัวอย่างโปรแกรมที่มีการใช้ pointer ชี้ไปยัง pointer

int int_data = 9;

int *int_ptr1;

int **int_ptr2;

int ***int_ptr3;

int_ptr1=&int_data;

int_ptr2=&int_ptr1;

int_ptr3=&int_ptr2;

วันศุกร์ที่ 2 เมษายน พ.ศ. 2553

Pointer คืออะไร

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

ถ้ายังงงๆอยู่ก็ขออธิบายเป็นภาษาคนละกันนะคับ คือว่า เวลาเราจะรับ-ส่ง ตัวแปรในfunction เราก็มักจะให้มัน return ค่าออกมา แล้วก็มีตัวแปรไปรับค่านั้น แต่ถ้าเรามาใช้ pointer เนี้ย เราก็สามารถไปแก้ที่ address ของมันได้เลย ไม่ต้องมารอรับค่า return อยู่!!

ความสะดวกของมันก็คือ ถ้าในกรณีที่เราต้องการค่าreturnจากfunction เพียงตัวเดียวก็คงจะเหมือนๆกับตัวแปรทั่วไป แต่ถ้าเป็น function ที่มีการ return หลายๆตัวแปรล่ะ ถ้าเราใช้ array แล้ว return ออกมาก็ได้ผลเหมือนกันแหละคับแต่ว่าถ้ามันเป็นคนละชนิดกันละ อิๆๆ

การกำหนดตัวแปร Pointer

การกำหนดตัวแปร Pointer จะคล้ายกับการกำหนดตัวแปรชนิดต่างๆ เพียงแต่ต้องมีเครื่องหมาย *หน้าชื่อตัวแปร ดังนี้

int *pt;

ในที่นี้กำหนดให้ pt เป็นตัวแปร Pointer ซึ่งเก็บ Address ของตัวแปรชนิด Integer

ในเรื่อง Pointer จะมีเครื่องหมายอยู่ 2 ชนิดคือ * และ & โดยเครื่องหมายแต่ละตัวจะมีหน้าที่ดังนี้

  • * จะเป็นการอ้างอิงถึงข้อมูลที่อยู่ใน address โดย address นี้จะเก็บอยู่ในตัวแปรแบบ Pointer เช่นในตัวอย่างคือ pt
  • & จะให้ค่า address ของตัวแปรที่อยู่หลังเครื่องหมายนี้

ตัวอย่าง

#include <iostream>

using namespace std;

int main() {

int *pt,a,b;

a=20;

pt=&a;

b=*pt;

cout<<"pt's address = "<<&pt<<endl;

cout<<"assign a = 20"<<endl;

cout<<"address of a = "<<&a<<endl;

cout<<"store address of a to pt,pt = "<<&a<<endl;

cout<<"assing b = data in address of pt(*pt),b = "<<b<<endl;

return 0;

}

***ข้อจำกัดในการใช้ตัวดำเนินการ&

- ห้ามใช้กับตัวคงที่

var_address = &100;

- ห้ามใช้กับนิพจน์ที่มีตัวดำเนินการ + และ /

int var1 = 100;

var_address = &(var1 + 10);

- ห้ามใช้กับตัวแปร register

register reg1;

var_address = &reg1;   //ตัวแปร register จะใช้ใน CPU โดยตรง

*ตัวแปรชนิด register ไม่ต้องมี addressที่หน่วยความจำสำหรับเก็บค่า