Pointer
Pointer ဆိုမွေတာ႔ ညႊန္ျပသူေပါ႔ ဗ်ာ ။ ညႊန္ျပတယ္ဆိုေတာ႔ သူကဘာေတြကိုညႊန္ျပမလဲ ဘယ္ေနရာမွာ ၊ ဘယ္နားေလးမွာ စတဲ႔ ေနရာကိုပဲ ညႊန္ျပမွာေပါ႔ ။ ဒါက ကၽြန္ေတာ္တို႔ အလြယ္ျမင္သာေအာင္လူၿပိန္းေတြးေတြးၾကည့္လိုက္တာေပါ႔ ။ သူကဘာလဲဆိုတာအေသးစိတ္ေဆြးေႏြးၾကည့္ရေအာင္ဗ်ာ ။ ကၽြန္ေတာ္တို႔ Program မွာ variable ေတြေၾကျငာလိုက္ပီဆုိတာနဲ႔ Computer ထဲမွာရွိတဲ႔ memory မွာ အဲဒီ variable ေလးေတြအတြက္ ေနရာေဝျခမ္းေရးေတြလုပ္ပါတယ္ ။ ဥပမာ ကၽြန္ေတာ္တို႔ က int a; နဲ႔ int b ; လို႔ variables ၂ ခုေၾကျငာလိုက္တယ္ဆိုပါေတာ႔ ။ မန္မိုရီႀကီး ထဲမွာ variable a အတြက္တစ္ေနရာ variable b အတြက္တစ္ေနရာ ေနရာသတ္မွတ္ေပးပါတယ္ ။ အဲလို integer variables ေတြအတြက္ memory ေပၚမွာ 4 bytes ေနရာေပးပါတယ္(32 bits computer မ်ားအတြက္) ။ တျခား char တို႔ float တို႔ စတဲ႔ data types ေတြကေနရာဘယ္ေလာက္ယူတယ္ဆိုတာ ကို ေဆြးေႏြးခ်က္ (၃) က DataTypes and Ranks ဆိုတဲ႔ဇယားမွာသြားၾကည့္နုိင္ပါတယ္ ။ အဲလို memory ထဲမွာ variable ေတြသတ္မွတ္ထားတဲ႔ေနရာကိုေတာ႔ အဲဒီvariable ရဲ့ address as လို႔ေခၚပါတယ္(တနည္း reference လုပ္တယ္လို႔လည္းေခၚပါေသးတယ္) ။ program ေရးတဲ႔အခါမွာေတာ႔ သူ႔ကို & (ampersand) နဲ႔ကိုယ္စားျပဳပါတယ္ ။Pointer ဆိုတာကေတာ႔ အဲဒီ variable ရဲ့ address ကို ညႊန္ျပပီး variable ေတြကိုေခၚသံုနုိင္တဲ႔အရာပါပဲ ။ Pointer ကိုေတာ႔ * (star sign)နဲ႔ကိုယ္စားျပဳပါတယ္ ။ ပထမဆံုး Variable ရဲ့ value (တန္ဖိုး) နဲ႔ address (ေနရာ) ကိုေကာင္းေကာင္းနားလည္ေအာင္ ေအာက္ကဥပမာေလး ၾကည့္ၾကည့္ပါ ။
Example Program
#include<iostream>
using namespace std;
int main()
{
int a,b;
a=200;
b=300;
cout<<"Value of a = "<<a<<endl;
cout<<"Address of a = "<<&a<<endl;
cout<<"Value of b = "<<b<<endl;
cout<<"Address of b = "<<&b<<endl;
return 0;
}
Result
ဒီ Program ေလးနဲ႔ Result ေလးကို တြဲၾကည့္မယ္ဆိုရင္ variable တိုင္းမွာ address ကိုယ္စီရွိတယ္ဆိုတာ နားလည္မယ္ထင္ပါတယ္ ။ အဲဒါကိုနားလည္ပီဆိုရင္ Pointer ေတြဘယ္လို ေၾကျငာလဲအသံုးျပဳလဲဆိုတာကို ၾကည့္ၾကည့္ရေအာင္ဗ်ာ ။
Declaring variables of pointer types
Variables ေတြကို Pointer Types အေနနဲ႔ေၾကျငာမယ္ဆိုရင္
Type * name;
ပံုစံေၾကျငာရမွာပါ ။ ဥပမာ
int * iNumber;
char * character;
float * fNumber;
အခု Pointer ဆိုတာဘာလဲသိသြားၿပီ Pointer ကိုယ္လုိေၾကျငာရလဲဆိုတာသိသြားၿပီ ။ ပိုၿပီးေတာ႔ အဓိပၸါယ္ရွိသြားေအာင္ Pointer ကိုဘာေၾကာင္႔သံုးရလဲဆိုတာကို ကၽြန္ေတာ္တို႔ ေဆြးေႏြးၾကည့္ရေအာင္ ။ ေအာက္က ပရိုဂရမ္ေလးၾကည့္ၾကည့္ပါ ။
Example Program
#include<iostream>
using namespace std;
int main()
{
int a,b;
a=200;
b=300;
cout<<"Value of a = "<<a<<endl;
cout<<"Address of a = "<<&a<<endl;
cout<<"Value of b = "<<b<<endl;
cout<<"Address of b = "<<&b<<endl;
a=500;
cout<<"Value of a = "<<a<<endl;
cout<<"Address of a = "<<&a<<endl;
a=1000;
cout<<"Value of a = "<<a<<endl;
cout<<"Address of a = "<<&a<<endl;
b=2;
cout<<"Value of b = "<<b<<endl;
cout<<"Address of b = "<<&b<<endl;
return 0;
}
Result
အခုနက တစ္ပုဒ္ကိုပဲ ထပ္ျဖည့္ထားတာပါ ။ သတိထားမိလားမသိဘူး ။ ကၽြန္ေတာ္ a နဲ႔ b အတြက္တန္ဖိုးေတြကိုေျပာင္းထည့္ေပးသြားတယ္။ ပီးေတာ႔ value နဲ႔ address ကိုထုတ္ေပးခိုင္းတယ္ ။ value ေတြသာခ်ိန္းသြားတယ္ address ကမေျပာင္းဘူး ။ ကၽြန္ေတာ္႔မွာခြက္တစ္ခု ရွိတယ္ပဲဆိုၾကပါစို႔ အဲဒီခြက္ကိုေရထည့္ေသာက္ေတာ႔ေရခြက္ျဖစ္တယ္ ။ ေကာ္ဖိထည့္ေတာ႔ေကာ္ဖီခြက္ျဖစ္တယ္ ။ အေအးထည့္ေသာက္ေတာ႔ အေအးခြက္ျဖစ္တယ္ ။ ေရ ၊ ေကာ္ဖိီ ၊အေအး စတဲ႔ တန္ဖိုးေတြဘယ္လိုေျပာင္ေျပာင္း ၊ထည့္တဲခြက္ကို ကၽြန္ေတာ္ က ကိုင္ထားတာျဖစ္တဲ႔အတြက္ ဘာလာလာေအးေဆးပဲေပါ႔ ။ အခုလည္း Program ထဲမွာ variable ရဲ့ value ေတြႀကိဳက္သလိုေျပာင္းပါ ကၽြန္ေတာ္က အဲဒီ variable ရဲ့ address ကို pointer နဲ႔ ျပပီးသံုးမယ္ဆိုရင္ အမ်ားႀကီးသက္သာသြားတာေပါ႔ ။ pointer ရဲ့တျခားေကာင္းက်ိဳးေတြလည္းရွိခ်င္ရွိဦးမွာပါ ။ ဒါကကၽြန္ေတာ္သိတာေလးကိုပဲေဆြးေႏြးတာပါ ။
Dereference operator (*)
Pointerေတြဟာ Address (reference) ေတြပဲ Point လုပ္ေပးနိုင္ပါတယ္ ValueေတြကိုPointလုပ္လို႔မရပါဘူး(စိတ္ထဲမွာအေသမွတ္ထားပါ) ။ ဒါေၾကာင္႔ Pointer ကို Output အေနနဲ႔ျပလိုက္မယ္ဆိုရင္ Address အေနနဲ႔ ပဲထြက္လာမွာပါ ။ တကယ္လို႔ ကၽြန္ေတာ္တို႔ က အဲဒီ Address မွာရွိတဲ႔ Value ကို Output ထုတ္ေပးခ်င္တယ္ဆိုရင္ေတာ႔ Deference Pointer (သို႔) Dereference Operator(*) ျပန္လုပ္ေပးရပါတယ္ ။ ေအာက္ကကုဒ္ေလးေတြကိုတစ္ခ်က္ၾကည့္ၾကည့္ပါ ။
double Num =10;
double dNum;
double *ptr=&Num // ၁၀ ဆိုတဲ႔ value ရွိရာ address ကို Pointer နဲ႔ point လုပ္လိုက္ပါတယ္ ။
cout<<ptr; // အခုတိုင္းထုတ္လိုက္ပီဆိုရင္ pointer ကို output ထုတ္တာျဖစ္လို႔ address ပဲထြက္လာမွာပါ ။
dNum=*ptr;
// ဒီ လုပ္ေဆာင္ခ်က္ေလးကိုေတာ႔ Dereference လုပ္တယ္လု႔ိေခၚပါတယ္။(ဒါကေတာ႔ Variable အလြတ္တစ္လံုးနဲ႔ Dereference လုပ္တာပါ)
cout<<dNum; // အခုတိုင္း ဆိုရင္ေတာ႔ နဂို value ျဖစ္တဲ႔ ၁၀ ဆိုတာကို output ထုတ္ေပးမွာျဖစ္ပါတယ္ ။
cout<<*ptr; // ဒီလုပ္ေဆာင္ခ်က္ဆိုရင္လည္း Dereference လုပ္တာပါပဲ ၁၀ ဆိုတာကို output ထုတ္ေပးမွာျဖစ္ပါတယ္ ။
Pointer Arithmetic
တျခား Variables ေတြ ကို Operation လုပ္ဖို႔အတြက္ Arithmetic Operator ေတြသံုးနုိင္သလို Pointer မွာလည္းသံုးနုိင္ပါတယ္ ။ ဒါေပမဲ႔ ပံုမွန္ data types ေတြ Arithmetic နဲ႔ေတာ႔ ျခားနားပါတယ္ ။ Pointer Arithmetic ေအာက္မွာ ဘယ္ Operators ေတြသုံးနိုင္လဲဆိုေတာ႔
+ , - , ++ , -- , += , -= , == , != , > , < , <= , >= စတဲ႔ Operators ေတြ အသံုးျပဳနိုင္ပါတယ္ ။ Pointer Arithmetic နဲ႔ ရိုးရိုး datatype ေတြရဲ့ Arithmetic ဘာကြာလဲဆိုတာ ကို ေအာက္က ဥပမာေလးေတြမွာ ေလ႔လာၾကည့္ရေအာင္ဗ်ာ ။
Example For Pointer Arithmetic
#include<iostream>
using namespace std;
int main()
{
int nValue = 8;
int *pnPtr = &nValue;
cout << pnPtr << endl;
cout << pnPtr+1 << endl;
cout << pnPtr+2 << endl;
cout << pnPtr+3 << endl;
return 0;
}
Result
Result န႔ဲ Code ေလးေတြကိုတြဲၾကည့္ၾကည့္ပါ ။ ပထမ မူရင္းPointer ရဲ့ Address ျဖစ္တဲ႔ 0013ff60 ဆိုတာကိုထုတ္ေပးတယ္ ။ အဲဒါ cout << pnPtr << endl; ဆိုတဲ႔ line အတြက္ေပါ႔ ။ ေနာက္ cout << pnPtr+1 << endl; ဆိုတဲ႔ line အတြက္က်ေတာ႔ 0013ff64 ဆိုၿပီးထုတ္ေပးပါတယ္ ။ code ေတြမွာ ကၽြန္ေတာ္က 1 ,2,3 ကိုအစဥ္လိုက္ေပါင္းပီးထုတ္သြားတာ ပါ ။ result မွာ 4 စီကြာသြားတာကိုေတြ႔မယ္ထင္ပါတယ္ ။ ေနာက္ဆံုး က 0013ff6c ဆိုတာကိုၾကည့္ၿပီး မ်က္စိမလည္ပါနဲ႔ ။ ႔ သူက hexadecimal တန္ဖိုးနဲ႔တြက္တာျဖစ္တဲ႔အတြက္ 0 ကေန f ထိဆိုေတာ႔ (0 1 2 3 4 5 6 7 8 9 A B C D E Fဆိုၿပီး ၁၆ လံုးရွိပါတယ္) C ဆိုတာ ၁၂ ကို ကိုယ္စားျပဳပါတယ္ ။ ဒါဆိုရင္ 0 , 4 , 8, 12 ဆိုၿပီး ၄ စီကြာသြားတာကိုသတိထားမိမွာပါ ။ ဟုတ္ၿပီ ၄ စီကြာတယ္ ဘာေၾကာင္႔ ၄ စီကြာလဲဆိုေတာ႔ data ေတြစေၾကျငာတုန္းက int nValue = 8; int *pnPtr = &nValue; ဆိုၿပီး integer ပါလို႔ ေၾကျငာခဲ႔တာျဖစ္တဲ႔အတြက္ 4 စီကြာသြားတာပါ ။ ေဆြးေႏြးခ်က္ (၃) က datatype and rank ဇယားကိုျပန္ၾကည့္ၾကည့္ပါ ။ integer ရဲ့ memory မွာေနရာယူတဲ႔ တန္ဖိုးက 4 bytes ရွိပါတယ္ ။ ဒါေၾကာင္႔ တစ္ခုနဲ႔ တစ္ခု 4 စီကြာသြားတာပါ ။ တကယ္လို႔ double နဲ႔ေၾကျငာခဲ႔မယ္ဆိုရင္ 8 စီကြာသြားပါလိမ္႔မယ္ ။ char နဲ႔ေၾကျငာရင္ 1 စီကြာၿပီး short နဲ႔ေၾကျငာရင္ ၂ စီကြာသြားတာကိုေတြ႔ပါလိမ္႔မယ္ ။ အေပၚက ဥပမာေလး ကိုပဲ data type ေျပာင္းေၾကျငာၿပီး ထုတ္ၾကည့္ၾကည့္ပါ ။
တကယ္လို႔ မရွင္းေသးဘူးဆိုရင္ ေအာက္ကပံုေလးပါထပ္ၾကည့္ပါ ဦး ။ &mychar (address of mychar) = 1000 လို႔သတ္မွတ္ထားပီး ++ ေအာ္ပေရတာသံုးလိုက္တဲ႔အခါ 1001 ဆိုၿပီး ၁ ပဲတိုးပါတယ္ ။ &myshort = 2000 လို႔သတ္မွတ္ၿပီး ++ ေအာ္ပေရတာကိုသံုးလိုက္တဲ႔ အခါမွာ 2002 ဆိုၿပီး ၂ တိုးတဲ႔ေနရာကိုေရာက္သြားတယ္ ။ &mylong = 3000 လို႔သတ္မွတ္ၿပီး ++ ေအာ္ပေရတာသံုးတဲ႔အခါမွာေတာ႔ 3004 ေနရာကိုေရာက္သြားတယ္ဆိုေတာ႔ 4 တိုးသြားတယ္ ။
၁ ေပါင္းတာခ်င္းတူေပမဲ႔ data types ေတြေပၚမူတည္ၿပီး ထြက္လာမဲ႔ result က်ေတာ႔ကြဲျပားသြားတယ္ ။ ရိုးရိုး arithmetic မွာေတာ႔ int a =1 ; a+1=2; double a=1; a+1=2 ; data types ေတြဘယ္လိုပဲေျပာင္းေၾကျငာေၾကျငာ ရလာမဲ႔ ရလာဒ္က တန္ဖိုး က data types ေတြေပၚမွာ မွီတည္မေနပါဘူး ။ အဲဒီအခ်က္ က ရိုးရိုး arithmetic နဲ႔ pointer arithmetic မတူတဲ႔အခ်က္ပါပဲ ။ ဒါဆိုရင္ Pointer Arithmetic ကို သေဘာေပါက္မယ္ထင္ပါတယ္ ။
Pointer And Array
Array အေၾကာငး္ကိုေတာ႔ မေဆြးေႏြးရေသးပါဘူး ။ Array ဆိုတာကေတာ႔ Variable name တစ္ခုတည္းမွာElements (value) တစ္ထပ္ပိုၿပီး သံုးခ်င္တဲ႔အခါမ်ိဳးမွာ Array နဲ႔ေရးတာ ပါ ။ အဲဒီ Array ထဲမွာလည္း Pointer ကိုသံုးနိုင္တာေၾကာင္႔ Pointers ေခါင္းစဥ္ေအာက္မွာ ထည့္ေဆြးေႏြးလိုက္တာပါ ။ Array ကို ေၾကျငာေတာ႔မယ္ဆိုရင္ ေအာက္ကတုိင္းေၾကျငာနိုင္ပါတယ္ ။
int anArray[5]={1,2,3,4,5}; // Integers 5 ခုပါတဲ႔ array တစ္ခုအျဖစ္ေၾကျငာလိုက္တာပါ ။
char chArray[] = “OnOurHands”; // character array တစ္ခုေၾကျငာလုိက္တာပါ ။
အခု က Array ကို Point လုပ္မဲ႔ Pointers ေတြအေၾကာင္းကိုေျပာမွာျဖစ္လို႔ Array အတြက္အေသးစိတ္ကိုေတာ႔ေနာက္မွာပဲေျပာပါေတာ႔မယ္
Pointer တစ္ခုနဲ႔ Array ကို Point လုပ္မယ္ဆိုရင္ Array ရဲ့ ပထမဆံုး Element Address ကိုပဲ Point လုပ္နုိင္မွာျဖစ္ပါတယ္ ။ Element အားလံုးရဲ့ Address ကို Pointers တစ္ခုတည္းနဲ႔ Point လုပ္လို႔မရပါဘူး ။ ေအာက္ကဥပမာေလးကိုေလ႔လာၾကည့္ပါ
#include<iostream>
using namespace std;
int main()
{
//declare and initialization of array
int iArray[5]={1,2,3,4,5};
char chArray[]="OnOurHands";
//declare Pointers
int *iPtr;
char *chPtr;
//Point Array
iPtr=iArray;
chPtr=chArray;
//deference and Output Pointer
cout<<*iPtr<<endl;
cout<<*chPtr<<endl;
//If you want to output all Elements , do like that
cout<<*(iPtr);
cout<<*(iPtr+1);
cout<<*(iPtr+2);
cout<<*(iPtr+3);
cout<<*(iPtr+4)<<endl;
for(int i=0;i<10;i++)
{
cout<<*(chPtr+i);
}
cout<<endl;
return 0;
}
Result
ရွင္းလင္းခ်က္
Array ေတြ Declare လုပ္တယ္ ။ ၿပီးေတာ႔ Pointers ေတြ Declare လုပ္တယ္ ။ Arrays ေတြကို Pointer ေတြနဲ႔ Point လုပ္လိုက္တယ္ ။ အဲဒါေတြၿပီးေတာ႔ cout<<*iPtr<<endl; cout<<*chPtr<<endl; ဆိုၿပီး Pointers ေတြ Derefence လုပ္ၿပီး Output ထုတ္ေပးလိုက္တဲ႔အခါ မွာ 1 ရယ္ O (အို) ရယ္ဆိုၿပီး Array ၂ ခု ရဲ့ ပထမဆံုး Element ၂ ခု ထြက္လာတာကိုေတြ႔ပါလိမ္႔မယ္ ။ ဒါဆိုရင္ Pointer ေတြ က Arrays ေတြရဲ့ ပထမဆံုး Element ကိုသာ Point လုပ္နိုင္တယ္ဆိုတာ သေဘာေပါက္ေလာက္ပါၿပီ ။ ေနာက္မွာေရးထားတာေတြကေတာ႔ ကၽြန္ေတာ္တို႔ က ပထမဆံုး Element တင္မဟုတ္ပဲ Array တစ္ခုမွာရွိတဲ႔ Elements ေတြကို Pointer နဲ႔ထုတ္ေပးခ်င္တဲ႔အခါ Pointer Arithmetic ကိုသံုးၿပီး ထုတ္ေပးတဲ႔ပံုစံ ေရးျပထားတာပါ ။ အဲဒါေၾကာင္႔ ပထမ Integer Array အတြက္
1 2 3 4 5 ေနာက္ Array အတြက္ OnOurHands ဆိုၿပီး Elements အားလံုးထြက္လာတာပါ ။
Pointer To Pointer
ရိုးရိုး Variable ေတြကို Pointers ေတြနဲ႔ Point လုပ္လို႔ရသလို Pointers ေတြကိုထပ္ၿပီး Pointers ေတြနဲ႔ Point လုပ္လို႔ရပါေသးတယ္ ။ အဲလိုလုပ္တာကို Pointer to Pointer လို႔ေခၚတာပါ ။ Pointer နဲ႔ Pointer ကိုထပ္ၿပီး Point လုပ္ဖို႔ အတြက္ ** (star ၂ လံုး) ကိုသံုးပါတယ္ ။ ဥပမာေလး ကိုၾကည့္လိုက္ရင္နားလည္မယ္ထင္ပါတယ္ ။
#include<iostream>
using namespace std;
int main()
{
char a;
//declare Pointer
char * b;
//declare Pointer to Pointer
char ** c;
//initialization
a = 'z';
b = &a;
c = &b;
//dereference and output Pointers
cout<<c<<endl;
cout<<*c<<endl;
cout<<**c<<endl;
return 0;
}
ပုံေလးကိုၾကည့္ၾကည့္ပါ ။ variable a ထဲမွာ z ဆိုတဲ႔ character value ရွိပါတယ္ ။ သူရဲ့ address ကေတာ႔ 7230 ပါ ။ b က a ကုိလွမ္းၿပီး point လုပ္တာျဖစ္လို႔ သူရဲ့ တန္ဖိုးသည္ 7230 ျဖစ္ၿပီး address 8092 ပါ ။ ေနာက္ခါ c က b ကိုထပ္ၿပိး Pointer to Pointer နဲ႔ထပ္ၿပီး Point လုပ္ထားတာ ျဖစ္လို႔ c တန္ဖိုးသည္ 8092 ျဖစ္ၿပီးေတာ႔ address ကေတာ႔ 10502 ပါ ။ အဲဒါကို Dereference လုပ္ခ်င္တယ္ဆိုရင္ေတာ႔
ဥပမာProgram မွာျပထားတဲ႔ အတုိင္းပဲ **c ဆိုမွ မူရင္းတန္ဖိုး z ကိုျပန္ရမွာျဖစ္ပါတယ္ ။
Null pointer
Null Pointer ဆိုတာကေတာ႔ မန္မိုရီေပၚက ဘယ္ Address (reference ) တန္ဖိုးမွ Point လုပ္မေပးတဲ႔ Pointer Type တစ္မ်ိဳးပါပဲ ။ တကယ္လို႔ Pointer ကို Deference လုပ္မယ္ဆိုရင္ ေတာ႔ int နဲ႔ Casting လုပ္ၿပီး မွ OutPut ထုတ္မယ္ဆိုရင္ေတာ႔ သူရဲ့တန္ဖိုး က ၀(သုည) ထုတ္ေပးမွာျဖစ္ပါတယ္ ။ Null Pointer ေၾကျငာေပးတဲ႔ပံုစံေလး ပါ ။
int * p;
p = 0; // p has a null pointer value
အေပၚမွာ ေဆြးေႏြးခဲ႔ တာေတြကိုနားလည္မယ္ဆိုရင္ Pointer အေၾကာင္းေတာ္ေတာ္ေလး သိေလာက္ၿပီထင္ပါတယ္ ။ ေနာက္ထပ္ Void Pointer တို႔ Pointer To function တို႔ အပိုင္းေတြရွိပါေသးတယ္ ။ ထပ္ၿပီး ပိုေလ႔လာခ်င္တယ္ဆိုရင္ေတာ႔
http://www.cplusplus.com/doc/tutorial/pointers/
http://www.java2s.com/Tutorial/Cpp/0220__Pointer/Catalog0220__Pointer.htm
တို႔မွာကိုယ္တုိင္ေလ႔လာနိုင္ပါတယ္ ။
ေဆြးေႏြးခ်က္ (၁၅)
Friday, September 3, 2010
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment