ေဆြးေႏြးခ်က္(၁၆)

Friday, September 3, 2010

Functions

Functions ေတြဆိုတာ Program ေတြမွာ မျဖစ္မေနပါတဲ႔ ပရိုဂရမ္အပိုင္းေလးေတြပဲျဖစ္ပါတယ္ ။ ဥပမာ main() {} ဆိုတာလည္း function တစ္ခုပါပဲ ။ function ေတြ ကိုဘာေၾကာင္႔ Program ထဲမွာထည့္သံုးရလဲဆိုေတာ႔ call ေခၚၿပီး သံုးလို႔ရလို႔ပါပဲ ။ Program ထဲမွာထပ္ခါထပ္ခါ လုပ္ေနရမဲ႔ အလုပ္ေတြကို ခဏခဏ ေရေနဖို႔မလိုပဲ တစ္ေနရာတည္းမွာ ဖန္ရွင္အေနနဲ႔ေရးထားၿပီး calling function အေနနဲ႔ ေခၚသံုးရင္ တိုလည္းတိုမယ္ ရွင္းလည္းရွင္းသြားပါတယ္ ။ function ေတြကိုသံုးမယ္ဆိုရင္ ေအာက္ပါအတိုင္းေရးၿပီးသံုးနိုင္ပါတယ္ ။

၁ ။ Return type FunctionName () { statements }

၂ ။ Return type FunctionName ( parameter1, parameter2, ...) { statements }

• ReturnType ဆိုတာကေတာ႔ Function ရဲ့ Return ျပန္ေပးမဲ႔ types အမ်ိဳးအစားျဖစ္ပါတယ္ ။ void , int , float , double စသည္ျဖင္႔ အမ်ိဳးမ်ိဳးျဖစ္နိုင္ပါတယ္ ။
• FunctionName ဆိုတာကေတာ႔ ဖန္ရွင္ကိုသတ္မွတ္ေပးမဲ႔နာမည္ပဲျဖစ္ပါတယ္ ။
• () ခ်ည္းပဲဟာကေတာ႔ parameters ေတြမပါတဲ႔ functionေတြအတြက္ပါ ။
• ( parameter1, parameter2, ...) ဆိုတာကေတာ႔ parameters ေတြ ဖန္ရွင္ထဲမွာကိုယ္သံုးရင္သံုးသေလာက္ ေၾကျငာေပးလို႔ရပါတယ္ ။ int a , float b စသည္ျဖင္႔ေပါ႔ ။
• { statements } ဆိုတာကေတာ႔ ကိုယ္လုပ္ခ်င္တဲ႔ ညြန္ၾကားခ်က္ေတြကိုေရးေပးရမဲ႔ေနရာပါ ။


Example For Function

// void function example
#include <iostream>
using namespace std;

void printmessage ()
{
cout << "First Function!";
}

int main ()
{
printmessage ();
cout<<endl;
return 0;
}

ရွင္းလင္းခ်က္

အေပၚက Program ေလးကို ၾကည့္မယ္ဆိုရင္ Function ၂ ခုသံုးထားတာကို ေတြ႔မွာျဖစ္ပါတယ္ ။
• ပထမ Function မွာ Return Type မွာ void ကိုသံုးထားပါတယ္ ။ ၿပီးေတာ႔ Parameters ေတြမပါပါဘူး ။ ဘာလို႔လဲဆိုေတာ႔ စာေၾကာင္းတစ္ေၾကာင္းကိုထုတ္ေပးယံု ပဲျဖစ္တဲပအတြက္ မလိုအပ္လို႔ ျဖစ္ပါတယ္ ။Function Statements မွာေတာ႔ First Function! ဆိုတဲ႔စာေၾကာငး္ေလးကိုထုတ္ေပးဖို႔ေရးထားပါတယ္ ။
• ေနာက္ဖန္ရွင္တစ္ခုကေတာ႔ main ဖန္ရွင္ပါ ။ Return type ကိုေတာ႔ int ေပးထားပါတယ္ ။ ဒါေၾကာင္႔ function statements ထဲမွာ return 0 ဆိုၿပီး ျပန္ေပးထားတာျဖစ္ပါတယ္ ။ printmessage(); ဆိုတာကေတာ႔ အေပၚ က ေရးထားတဲ႔ Function ကို main function ထဲကေန Call ေခၚထားတာျဖစ္ပါတယ္ ။


Function ေတြကုိေၾကျငာျခင္း

Function ေတြကိုအေပၚမွာ ျပထားတဲ႔ ဥပမာအတုိင္း တန္းေရးၿပီးသံုးနိုင္သလို ပထမဆံုး main function အတိုင္ခင္မွာ ေၾကျငာၿပီးလည္းသံုးနိုင္ပါတယ္ ။ အဲလို main function မတိုင္ခင္ ေၾကျငာလုိက္တဲ႔ Prototype Function လို႔ေခၚပါတယ္ ။ သူ႔ရဲ့ အသံုးျပဳပံုကိုေအာက္မွာတစ္ခ်က္ၾကည့္ၾကည့္ပါ ။


Example For Prototype Function

// void function example
#include <iostream>
using namespace std;

void printmessage ();

int main ()
{
printmessage ();
cout<<endl;
return 0;
}
void printmessage ()
{
cout << "Declaration Function! (OR) Prototype ";
}

ဖန္ရွင္ေတြကို Prototype ဖန္ရွင္ေတြအျဖစ္ေၾကညာၿပီးသံုးမယ္ဆိုရင္ေတာ႔အေပၚမွာျပထားခဲ႔တဲ႔တိုင္းပဲ ကိုယ္ သံုးခ်င္တဲ႔ ဖန္ရွင္ေတြကို main function မတိုင္ခင္မွာေၾကျငာခဲ႔ရမွာျဖစ္ပါတယ္ ။

Prototype ကိုေၾကျငာတဲ႔ခါမွာ void printmessage (); သို႔မဟုတ္ int Add (int , int ,float); စတဲ႔ပံု စံေတြနဲ႔ ေၾကျငာနိုင္ပါတယ္ ။ အဲဒီမွမျဖစ္မေနသတိထားရမွာ က ( ; ) ပိတ္ခဲ႔ဖို႔ ေမ႔လို႔မရဘူးဆိုတာပါပဲ ။ ပီးေတာ႔ int Add (int , int ,float); ပံုစံ Parameters ေတြနဲ႔ prototype ေၾကျငာတဲ႔အခါ Parameters တစ္ခုနဲ႔တစ္ခုၾကား က ( , )ေကာ္မာ ခံ ၿပီးေရးတယ္ဆိုတာပါပဲ ။ စၿပီးေလ႔လာတဲ႔သူေတြအဖို႔မွားတက္တာေလးေတြက အဲဒါေလးေတြပါ ။

ေနာက္ တစ္ခ်က္ကေတာ႔ အေပၚ က Prototype ေၾကျငာတဲ႔အခါမွာ Parameters မပါတဲ႔ Function ဆိုလွ်င္လည္းမပါတဲ႔တိုင္း Parameters ေတြပါတဲ႔ဖန္ရွင္ဆိုရင္ လည္း Parameters ေတြပါတဲ႔အေရအတြက္ ေၾကျငာထားခဲ႔တဲ႔တိုင္း ေအာက္ကဖန္ရွင္ေရးတဲ႔အခါမွာ ျပန္လည္းအသံုးျပဳဖို႔ ပါ ။ ေနာက္တစ္ခ်က္က Prototype ေၾကျငာတုန္းက function ေနာက္မွာ ( ; ) နဲ႔ပိတ္ခဲ႔ေပးရေပမ႔ဲ main function ေအာက္ Function စေရးတဲ႔အခါမွာေတာ႔ ( ; ) ပါလို႔မရပါဘူး ။ အေပၚ က ေရးထားတဲ႔ကုဒ္ေလးေတြကိုေသခ်ာျပန္ၾကည့္ၾကည့္ပါ ။

ေနာက္တစ္ခ်က္ကေတာ႔ ကိုယ္သံုးခဲ႔တဲ႔ ဖန္ရွင္ကို main function မွာ call ျပန္ေခၚဖို႔ေမ႔လို႔မရပါဘူး ။ ေမ႔ေနခဲ႔တယ္ဆိုရင္ေတာ႔ ကိုယ္လိုခ်င္တဲ႔အေျဖထြက္မွာမဟုတ္ပါဘူး ။


Pass The Variables By Value

C++ က Function ေတြမွာ Passing လုပ္တယ္ Pass လုပ္တယ္ဆိုတာ Data ေတြကို တစ္ေနရာကေနတစ္ေနရာ ေျပာငး္ေရႊ႔ေပးတာပါပဲ ။ အဲလိုေျပာငး္ေရႊ႔တဲ႔နည္းေတြ အမ်ိဳးမ်ိဳးရွိၾကပါတယ္ ။ value , pointer , reference , const , စသည္ျဖင္႔ pass လုပ္ေပးနိုင္တဲ႔ နည္းေတြအမ်ားႀကီးရွိပါတယ္ အခုေျပာမွာကေတာ႔ value နဲ႔ pass လုပ္ေပးတဲ႔နည္းပါ ။ ေအာက္ကကုဒ္ေလးေတြကိုၾကည့္ၾကည့္ပါ

Void f(int n)
{
n++;
}


int main()
{
int x = 2;
f(x);
cout << x;
}

Variables ေတြကို value ေတြနဲ႔ pass လုပ္တဲ႔အခါမွာ Call ေခၚခံရတဲ႔ဖန္ရွင္ရဲ့ parameters ေတြကို copy ပဲယူတာပါ ။ အေပၚက f ဖန္ရွင္မွာ က parameter ကို int n ဆုိၿပီးေၾကျငာထားတာပါ ။ ဒါေပမဲ႔ mainဖန္ရွင္မွာေတာ႔f(x);ဆိုၿပီးေရးထားတာကိုေတြ႔မွာပါ။ f ဖန္ရွင္ထဲက parameter ဟာ n မဟုတ္ေတာ႔ပဲ x ျဖစ္သြားတာကိုသတိထားမိမွာပါ ။ main ဖန္ရွင္ထဲမွာ int x=2; ဆိုၿပီး တန္ဖိုးတစ္ခုထည့္ၿပီးသားျဖစ္တဲ႔အတြက္ f(2); ဆိုတဲ႔ပံုစံမ်ိဳးဝင္သြားပါတယ္ အဲဒီ 2 ဆိုတဲ႔ value ဟာ call ေခၚခံရတဲ႔ f ဖန္ရွင္ရဲ့ parameter ျဖစ္တဲ႔ n ေနရာမွာဝင္သြားပါတယ္ ။ အဲဒါကို Data Passing လုပ္တယ္လို႔ေခၚပါတယ္ ။ f ဖန္ရွင္ ရဲ့ statement မွာ n++ ဆိုတဲ႔ အတြက္ 2 ကို တစ္တိုးၿပီး cout << x; ထုတ္ေပးတဲ႔အခါ ၃ ဆိုၿပီးထြက္မွာျဖစ္ပါတယ္ ။ ဒါကေတာ႔ Value ေတြ နဲ႔ function ေတြမွာ pass လုပ္ေပးတဲ႔နည္း ပါ ။
ပိုၿပီးနားလည္သြားေအာင္ ေအာက္က ဥပမာကိုထပ္ၾကည့္ၾကည့္ပါ ။


#include <iostream>
using namespace std;

double RigArea(double,double);

int main ()
{
double area = RigArea(20,30);
cout<<"\nLength = "<<30;
cout<<"\nWidth = "<<20;
cout<<"\nArea of Rightangle = "<<area<<endl;
return 0;
}
double RigArea(double W,double L)
{
return W*L;
}


• Program စစ ခ်င္းမွာ ဆိုရင္ အေပၚ function ေတြေၾကျငာျခင္း မွာတုန္းကေျပာထားခဲ႔တဲ႔တိုင္းပဲ main () ဖန္ရွင္ရဲ့အေပၚမွာ RigArea ဆိုတဲ႔ prototype ကိုေၾကျငာလိုက္ပါတယ္ ။ အဲဒီ Prototype မွာဆိုရင္ return type က double ျဖစ္ပီးေတာ႔ Parameters ေတြကိုလည္း double ၂ ခုအေနနဲ႔ေၾကျငာေပးထားပါတယ္ ။
• ေနာက္ main ဖန္ရွင္ထဲမွာ area ဆိုတဲ႔ variable တစ္ခုကို double အေနနနဲ႔ေၾကျငာၿပီး RigArea ဆိုတဲ႔ ဖန္ရွင္ကို call ေခၚလိုက္ပါတယ္ အဲလို call ေခၚရာမွာ pass လုပ္ေပးရမဲ႔ arguments ေတြကို တစ္ခါတည္းထည့္ေပးထားပါတယ္ ။
• အဲလို constant value ရွိတဲ႔ arguments ေတြ ကို ေကာ္ပီ ယူၿပီး ေအာက္မွာရွိတဲ႔ RigArea ဆိုတဲ႔ ဖန္ရွင္က parameters ေတြျဖစ္တဲ႔ W နဲ႔ L တို႔မွာ ထည့္လိုက္ပါတယ္ ။ အဲဒါဆိုေတာ႔ W=20 နဲ႔ L = 30 ဆိုတဲ႔သေဘာျဖစ္သြားပါတယ္ ။
• RigArea ဆိုတဲ႔ဖန္ရွင္ထဲမွာ ကၽြန္ေတာ္ က W*L ကိုေျမွာက္ပီး return ျပန္ေပးပါလို႔ ခိုင္းထားတဲ႔အတြက္ 20x30 =600 ဆိုတဲ႔ တန္ဖိုးကို return ျပန္ေပးပါတယ္ ။
• ဟုတ္ၿပီး main () ဖန္ရွင္ထဲမွာတစ္ခ်က္ျပန္ၾကည့္ၾကည့္ရေအာင္ double area = RigArea(20,30); လို႔ကၽြန္ေတာ္ကေရးထားတယ္။ ဒါေၾကာင္႔ RigArea(20,30); ကေနထြက္လာတဲ႔ ၆၀၀ ဆိုတဲ႔တန္ဖိုးဟာ area ဆိုတဲ႔ variable ထဲကိုဝင္သြားပါတယ္ ။ function call ေခၚပီးတဲ႔အခ်ိန္မွာ area ထဲမွာ 600 ဆိုတဲ႔တန္ဖိုးရွိေနပါၿပီ ။
• ေနာက္ ကၽြန္ေတာ္ထည့္ခဲ႔တဲ႔ Length နဲ႔ Width တို႔ရဲ့ constant တန္ဖိုးေတြကို ထုတ္ေပးတယ္ ။
• ေနာက္ဆံုးမွာေတာ႔ area ကို output ထုတ္ေပးလိုက္ပါတယ္ ။ အဲဒါေၾကာင္႔ အေျဖမွာ ၆၀၀ ဆိုၿပီးထြက္သြားတာပါ ။Result ကိုၾကည့္ၾကည့္ပါ ။

Result




Pass variables by Reference

Pointer အေၾကာင္းေဆြးေႏြး Reference (address as) အေၾကာင္းကိုေျပာခဲ႔တာမွတ္မိမယ္ထင္ပါတယ္ ။ value ေတြနဲ႔ pass လုပ္တဲ႔နည္းကိုအေပၚမွာေဆြးေႏြးခဲ႔ၿပီးၿပီ ။ value နဲ႔ pass လုပ္တယ္ဆိုတာ တိတိက်က်သတ္မွတ္လို႔ရတဲ႔ တန္ဖိုး ၊ variable ေတြနဲ႔ ေရႊ႔ေျပာင္းမွဳလုပ္ရာမွာ အဆင္ေျပေပမဲ႔ အမ်ိဳးမ်ိဳးျဖစ္လာနိုင္တဲ႔ တန္ဖိုးေတြအတြက္က်ေတာ႔ ခက္ခဲပါလိမ္႔မယ္ ။ အဲလိုအေျခအေနမွာ value ေတြ memory မွာတည္ေနတဲ႔ address (Reference) ကိုကိုင္ၿပီး pass လုပ္မယ္ဆိုရင္ အဲဒီေနရာမွာဘယ္တန္ဖိုးပဲဝင္ဝင္ ကၽြန္ေတာ္တို႔ကေနရာကို ကိုင္ထားတာျဖစ္တဲ႔အတြက္ လြယ္လြယ္ကူကူနဲ႔အဆင္ေျပပါတယ္ ။ အဲဒါေၾကာင္႔ Pass variable by Reference ကလည္း အေရးပါတဲ႔ passing ways တစ္မ်ိဳးပါပဲ ။ ေအာက္ကဥပမာေလးကိုၾကည့္ၾကည့္ပါ ။

// passing parameters by reference
#include <iostream>
using namespace std;

void duplicate (int&, int&, int&);
int main ()
{
int x, y, z;
cout<<"Three numbers for x ,y ,z "<<endl;
cin>>x>>y>>z;
duplicate (x, y, z);
cout << "x=" << x << ", y=" << y << ", z=" << z<<endl;
return 0;
}
void duplicate (int& a, int& b, int& c)
{
a*=2;
b*=2;
c*=2;
}

ရွင္းလင္းခ်က္

• Prototype declaration ကိုေသခ်ာၾကည့္ၾကည့္ပါ ။ return type ကို void အေနနဲ႔ေၾကျငာထားပါတယ္ ။ အဲဒါေၾကာင္႔ return value မရွိပါဘူး ။ ေနာက္ၿပီး Parameters list မွာ int& ဆိုၿပီး ၃ ခုေၾကျငာေပးထားပါတယ္ ။ အဲဒါေတြကေတာ႔ reference ေတြပါပဲ ။
• main () ဖန္ရွင္ထဲမွာ စစခ်င္း variables ၃ ခုကို integers အျဖစ္ေၾကျငာလုိက္ပါတယ္ ။ ပီးေတာ႔ အဲဒီ ၃ ခုအတြက္ user ကိုရိုက္ထည့္ေပးခိုက္ပါတယ္ ။ ကၽြန္ေတာ္ က ၂ ၊ ၄ ၊ ၆ လို႔ရိုက္ထည့္ေပးလိုက္တယ္ဆိုပါေတာ႔ ။ x=2 , y =4 , z=6 လို႔ဝင္သြားပါတယ္ ။
• ေနာက္ duplicate ဖန္ရွင္ကို call ေခၚပါတယ္ ။ အဲဒီမွာ စပါၿပီ ။ pass by value တုန္းက arguments to arguments ေကာ္ပီလုပ္သြားေပမဲ႔ ။ pass by reference မွာက်ေတာ႔ argument to reference အျဖစ္သြားပါတယ္ ။ ဒါေၾကာင္႔ထည့္လိုက္တ႔ဲ တန္ဖိုးေတြက duplicate ဖန္ရွင္ရဲ့ reference အသီးသီးမွာရွိတဲ႔ တန္ဖိုးေတြေနရာမွာဝင္သြားတယ္ေပါ႔ဗ်ာ ။
• x ရဲ့တန္ဖိုးကို a ကေကာ္ပီကူးတာျဖစ္လို႔ a*=2; ဆိုတဲ႔အတြက္ &a ဆိုတဲ႔ေနရာမွာ ၄ ဆိုတဲ႔ တန္ဖိုးတစ္ခုရွိေနပါၿပီ ။ေနာက္ထပ္ y တန္ဖိုး ၊ z တန္ဖိုးေတြသည္းလည္း ထိုနည္းအတိုင္းအသီးသီး လုပ္ေဆာင္ၾကၿပီး &b , &c ဆိုတဲ႔ေနရာေတြမွာ ၈ ၊ ၁၂ ဆိုၿပီးတန္ဖိုးအသီးသီးေရာက္သြားပါတယ္ ။ ပထမ main ဖန္ရွင္ ကေနအသြားမွာ 2 , 4, 6 ဆိုတဲ႔ arguments ေတြနဲ႔ argument to reference ပံု စံ သြားတာျဖစ္ၿပီး ၊ duplicate ဖန္ရွင္ထဲကေန main () ကိုျပန္တဲ႔ အခါမွာေတာ႔ေျပာင္းျပန္ reference to arguments ျဖစ္သြားတာပါတယ္ ။ ဒါေၾကာင္႔ references အသီးသီးမွာရွိေနၾကတဲ႔ 4 , 8, 12 ဆိုတဲ႔တန္ဖိုးေတြက main () ဖန္ရွင္ဆီကိုအသီးသီး ျပန္ဝင္သြားၾကပါတယ္ ။
• duplicate ဖန္ရွင္ကို call ေခၚအၿပီး x,y,z တိုရဲ့ တန္ဖိုးေတြကိုထုတ္ၾကည့္တဲ႔အခါမွာေတာ႔ ေအာက္က result မွာျမင္ရတဲ႔အတိုင္းပါပဲ

Result



Default values in parameters

Functions ေတြအသံုးျပဳဖို႔အတြက္ Prototype Function အျဖစ္ေၾကျငာရာမွာ parameters ေတြကို ၊ ဒါမွမဟုတ္ parameters ေတြထဲမွ ကိုယ္ႀကိဳက္သေလာက္အေရအတြက္ကို default value အေနနဲ႔ေပးထားလို႔ရပါတယ္ ။ function call ေခၚလိုက္တဲ႔အခါ မွာ pass လုပ္ေပးမဲ႔ value ေတြမရွိဘူးဆိုရင္ မူရင္း default argument ကို ထည့္ေပးမွာျဖစ္ပါတယ္ ။ ဥပမာကိုၾကည့္ၾကည့္ ပါ ။

#include <iostream>
using namespace std;

void f(int x = 0, int y = 50);

int main()
{
f(1, 2);
f(10);
f();
return 0;
}

void f(int x, int y)
{
cout << "\nx: " << x << ", y: " << y << "\n\n";
}

ရွင္းလင္းခ်က္

• Prototype ေၾကျငာထားတာကိုၾကည့္ၾကည့္ပါ ။ int x=0 , int y = 50 ဆို ၿပီး default argument တန္ဖိုးေတြထည့္ထားတာကိုေတြ႔ရပါလိမ္႔မယ္ ။ အဲဒါဆိုရင္ x နဲ႔ y ထဲမွာတန္ဖိုးအသီးသီးဝင္ၿပီးသား ျဖစ္သြားပါတယ္ ။ ဒါေပမဲ႔ main () ဖန္ရွင္မွာၾကည့္ၾကည့္ပါ ။
• f (1,2) ဆိုၿပီး f ဖန္ရွင္ကို call ေခၚလိုက္ပါတယ္ အဲဒီ 1 နဲ႔ 2 က function pass by value နည္းနဲ႔ ေအာက္က f ဖန္ရွင္ထဲဝင္သြားၿပီး ။ x နဲ႔ y ကိုထုတ္ေပးတဲ႔အခါမွာ ။ ၁ နဲ႔ ၂ ထြက္လာတာ ေတြ႔ပါလိမ္႔မယ္ ။
• ေနာက္ f (10) ဆိုၿပီး function call ေခၚလိုက္တဲ႔အခါမွာေတာ႔ f ဖန္ရွင္ထဲမွာ argument ကတစ္ခုတည္းျဖစ္ေနပါတယ္ ။ အဲလို တစ္ခုတည္းျဖစ္ရင္ အစဥ္တုိင္း ျဖစ္တဲ႔အတြက္ ေအာက္ က f ဖန္ရွင္ရဲ့ x ေနရာမွာဝင္သြားပါတယ္ ။ ဒါေၾကာင္႔ x တန္ဖိုး ၁၀ နဲ႔ y မွက default တန္ဖိုးျဖစ္တဲ႔ ၅၀ ကိုထုတ္ေပးမွာျဖစ္ပါတယ္ ။
• ေနာက္ f() ဆိုၿပီး function call ေခၚတဲ႔အခါမွာေတာ႔ argument တစ္ခုမွမပါတာျဖစ္လို႔ မူရင္း default value ေတြျဖစ္ၾကတဲ႔ x တန္ဖိုး ၀ နဲ႔ y တန္ဖိုး ၅၀ တို႔ကို ထုတ္ေပးမွာျဖစ္ပါတယ္ ။result မွာၾကည့္ၾကည့္ပါ ။

Result



Inline Function

Function ေတြ ကိုသံုးတဲ႔အခါမွာ ပထမဖန္ရွင္တစ္ခု ေဆာက္လိုက္တယ္ ပီးေတာ႔ အဲဒီ ဖန္ရွင္ကို main ဖန္ရွင္ကေနေခၚတယ္ ။ ေနာက္ၿပီး ေဆာက္ထားတဲ႔ဖန္ရွင္ ကေန main () ဖန္ရွင္ဆီကိုျပန္သြားတယ္ ။ အဲလိုေတြအလုပ္လုပ္ေနတာျဖစ္လို႔ တည္ေဆာက္တဲ႔ဖန္ရွင္ က ႀကီးရင္မေျပာပေလာက္ေပမဲ႔ တကယ္တမ္း ဖန္ရွင္မွာေရးထားတဲ႔ အလုပ္လုပ္ဖို႔ရွိတာ ကနည္းနည္းေလး ဆိုရင္ေတာ႔ ဖန္ရွင္လုပ္ေဆာင္ဖို႔အခ်ိန္ထက္ သြားလိုက ျပန္လိုက္လုပ္ေနမဲ႔အခ်ိန္က ပိုမ်ားပါမယ္ ။ အဲလိုေသးငယ္တဲ႔ဖန္ရွင္ေလးေတြကိုတည္ေဆာက္မယ္ ဆိုရင္ အခ်ိန္ကုန္သက္သာေအာင္ inline function ကိုသံုးပါတယ္ ။ inline function တစ္ခုတည္ေဆာက္မယ္ ဆိုရင္ေတာ႔ ပံုမွန္ function ေတြ ေရွ့မွာ inline ဆိုတဲ႔ keyword ေလးထည့္ေပးရံုပါပဲ ။ သူရဲ့ ပံုစံကေတာ႔

Inline returnType functionName (arguments….){statements….}


Example for inline function

#include <iostream>
using namespace std;

inline int max(int a, int b)
{
return a>b ? a : b;
}

int main()
{
cout << max(10, 20)<<endl;
cout << max(99, 88)<<endl;

return 0;
}

ရွင္းလင္းခ်က္

• Maximum ကိုရွာေပးမဲ႔ max() function ကိုၾကည့္ၾကည့္ပါ ေရွ့ဆံုး ကမွာ inline ဆိုတဲ႔ keyword ေလးကို သတိထားမိမွာပါ ။ အဲဒါေတာ႔ inline ဖန္ရွင္တစ္ခုအသံုးျပဳတဲ႔ပံုစံပါ ။ ဖန္ရွင္ရဲ့ အလုပ္လုပ္မဲ႔ statements ေလးကတကယ္ကို နည္းနည္းေလးပါ ။ အဲလို ဖန္ရွင္မ်ိဳးေတြဆိုရင္ inline ကိုသံုးတာပါ ။
• ဂဏန္ ၂ လံုးတစ္စံုဆီရဲ့ အႀကီးဂဏန္းကိုရွာေပးမဲ႔ ပံုစံေလးပါ ။ max ဖန္ရွင္ထဲမွာေတာ႔ operator ? ကိုသံုးထားတာပါ ။ သူ႔ရဲ့အလုပ္လုပ္ပံုကိုေတာ႔ ေဆြးေႏြးခ်က္(၄) Operators ေတြအေၾကာင္းတုန္း က conditional operator အျဖစ္ေဆြးေႏြးခဲ႔ဖူးပါတယ္ ။ ပထမကိန္း ဟာ ဒုတိယကိန္းထက္ႀကီးသလား ? ႀကီးရင္ ပထမကိန္း a ကိုထုတ္ေပးပါ : မဟုတ္ရင္ေတာ႔ ဒုတိယကိန္းကိုထုတ္ေပးပါလို႔ခိုင္းထား တာပါ ။ ဒီေလာက္ဆိုရင္သေဘာေပါက္မယ္ထင္ပါတယ္။ Result ကိုၾကည့္ၾကည့္ပါ ။

Result




Overloaded Function

C++ မွာ Function ေတြအမ်ားႀကီးကို နာမည္တစ္ခုတည္းေပးၿပီး ဖန္တီးနိင္ပါတယ္ ။ ဒါေပမဲ႔ return type တုိ႔ parameters type ေတြ ပါဝင္တဲ႔အေရအတြက္ေတြေတာ႔ကြဲျပားပါလိမ္႔မယ္ ။ အဲဒါ နာမည္တူနဲ႔ ဖန္ရွင္တစ္ခု ထက္ပိုသံုးတာကို overload လုပ္တယ္လို႔ေခၚပါတယ္ ။ C++ မွာ OOP ရဲ့ concept တစ္ခုျဖစ္တဲ႔ Polymophism ရဲ့ ပံုစံျဖစ္ပါတယ္ ။ Polymophism အေၾကာင္းကိုေတာ႔ ေနာက္မွပဲ ေဆြးေႏြးပါေတာ႔မယ္ ။ အခုကေတာ႔ overload ဆိုတာဘာလဲသိရင္အဆင္ေျပပါၿပီ ။ ဥပမာေလး ကိုၾကည့္ၾကည့္ပါ ။

Example

// overloaded function
#include <iostream>
using namespace std;

int operate (int a, int b);
float operate (float a, float b);
int main ()
{
int x=5,y=2;
float n=5.0,m=2.0;
cout << operate (x,y);
cout << "\n";
cout << operate (n,m);
cout << "\n";
return 0;
}

int operate (int a, int b)
{
return (a*b);
}

float operate (float a, float b)
{
return (a/b);
}

ရွင္းလင္းခ်က္

Prototype Function ကိုၾကည့္ၾကည့္ပါ operate ဆုိတဲ႔ နာမည္တူ ဖန္ရွင္ႏွစ္ခုကို သတိထားမိမယ္ထင္ပါတယ္ ။ ဒါေပမဲ႔ တစ္ခုက integer ျဖစ္ၿပီးတစ္ခုကေတာ႔ float အမ်ိဳးအစားျဖစ္ပါတယ္ ။ က်န္တဲ႔ ဖန္ရွင္ call ေခၚတာေတြ အလုပ္လုပ္ပံုေတြကေတာ႔ အေပၚဖန္ရွင္ေတြအေၾကာင္းအမ်ားႀကိး ေဆြးေႏြးခဲ႔ၿပိးျဖစ္လို႔ ထက္မေဆြးေႏြးေတာ႔ပါဘူး ။ နာလည္လိမ္႔မယ္လို႔ထင္ပါတယ္ ။



Recursivity

Recursion Function ရဲ့ဂုဏ္သတၱိကေတာ႔ တျခား ဖန္ရွင္တစ္ခုေန ေနာက္ဖန္ရွင္တစ္ခုကို call ေခၚသလိုမဟုတ္ပါဘူး ။ တျခားဖန္ရွင္တစ္ခုကေန ေနာက္ဖန္ရွင္တစ္ခုကို call ေခၚတယ္ဆိုရင္ ေခၚၿပီးတာနဲ႔ အေျဖတန္းထုတ္ေပးပါတယ္ ။ recursion function မွာေတာ႔ ကိုယ္႔ဘာသာ ပဲျပန္ေခၚေနၿပီး လိုခ်င္တဲ႔ အေျဖကို မထြက္မခ်င္း looping ပတ္ေနပါတယ္ ။ လိုခ်င္တဲ႔ ပြဳိင္႔အေျဖကိုေရာက္ၿပီဆိုမွ အေျဖထုတ္ေပးတဲ႔ Method တစ္မ်ိဳးပါပဲ ။ Function ေတြမွာ အဲလို ဂုဏ္သတၱိေတြ အသံုးျပဳနုိင္ပါတယ္ ။ ဥပမာေလးကိုၾကည့္ၾကည့္ပါ ။

// recursion function
#include <iostream>
using namespace std;

long factorial (long a)
{
if (a > 1)
return (a * factorial (a-1));
else
return (1);
}

int main ()
{
long number;
cout << "Please type a number: ";
cin >> number;
cout << number << "! = " << factorial (number);
return 0;
}

ရွင္းလင္းခ်က္

• ဒီဥပမာေလး က ဂဏန္းေတြရဲ့ Factorial တန္ဖိုးကိုရွာေပးမဲ႔ Program ေလးပါ ။
• Factorial ရွာတဲ႔ ပံုသနည္းကေတာ႔ n! = n * (n-1)! ပါ ။ ဥပမာ ကၽြန္ေတာ္တို႔ က 3 factorial ကိုရွာမယ္ဆိုရင္ 3 ! = 3*2! , 2!= 2* 1 ! ပါ ။ အားလံုး ေပါင္းေရးလိုက္တဲ႔အခါ မွာ 3 ! = 3*2*1 ရွာခ်င္တဲ႔ ဂဏန္း ကေန 1 အထိ ေျမွာက္သြားတာပါ ။
• Program မွာ main() function ကိုၾကည့္ၾကည့္ပါ ။ factorial တန္ဖိုးရွာဖို႔အတြက္ ဂဏန္းတစ္လံုးေပးပါဆိုၿပီးေတာင္ထားပါတယ္။ user ကေန တန္ဖိုးတစ္ခုရိုက္လိုက္ရင္ number ဆိုတဲ႔ variable နဲ႔ဖမ္းလိုက္တယ္ ။ ၿပီးေတာ႔ factorial ဖန္ရွင္ ကို call ေခၚပါတယ္။
• Call ေခၚစဥ္က ဝင္လာတဲ႔ argument ကို factorial ဖန္ရွင္က a ထဲကို ေကာ္ပီထည့္လိုက္ပါတယ္ ။ ၿပီးေတာ႔ ဖန္ရွင္ statements ထဲကိုဆင္းသြားၿပီး if နဲ႔စစ္ေဆးပါတယ္ ။ user ထည့္လုိက္တဲ႔ တန္ဖိုး ဟာ ၁ ထက္ႀကီးသလား ႀကိးတယ္ဆိုရင္ recursion စလုပ္ပါတယ္ ။ ဘယ္မွာလုပ္တာလဲဆိုေတာ႔ ပထမ ထည့္လိုက္တဲ႔ တန္ဖိုးက a ေနရာမွာဝင္တာဆိုေတာ႔ a* လို႔သိၿပီးတာနဲ႔ factorial (a-1) ဆိုၿပီး ဖန္ရွင္ကို call ျပန္ေခၚလိုက္တာပါ ။ အဲလိုနဲ႔တစ္ခါ a-1 တန္ဖိုးကို if နဲဲ႔ျပန္စစ္ပါတယ္ ။ အဲလိုနဲ႔ user ထည့္လိုက္တဲ႔တန္ဖိုးကို ၁ ေလွ်ာ႔ေလွ်ာ႔သြားၿပီး ၁ နဲ႔ညီတဲ႔အထိ ေလွ်ာ႔သြားပါတယ္ ။ ၁ နဲ႔ညီသြားၿပီဆိုရင္ေတာ႔ looping ကေနရပ္ၿပီး ေနာက္ဆံုးအေျဖကို ထုတ္ေပးမွာျဖစ္ပါတယ္ ။ ဒါဟာ Recurisivity ပါပဲ ။
• Variable နာမည္ေတြနဲ႔ရွင္းျပေတာ႔နည္းနည္း ရွဳပ္သြားတယ္ထင္တယ္ ။ ဥပမာ ကၽြန္ေတာ္က ေနၿပီး ၄ ရဲ့ factorial ကိုရွာေပးပါဆိုၿပီးထည့္ေပးလိုက္တယ္ဆိုပါေတာ႔ ။ factorial ဖန္ရွင္ကို call စေခၚပါတယ္ ပီးေတာ႔ ကၽြန္ေတာ္ထည့္လိုက္တဲ႔ 4 ဆိုတဲ႔ တန္ဖိုးကို if (4>1) ဆိုၿပီးစစ္လိုက္တယ္ ။ ႀကီး ေနတာျဖစ္တဲ႔အတြက္ 4*factorial(4-1) ဆိုတဲ႔ပံုစံျဖစ္သြားတယ္ ။ အဲဒီေတာ႔ factorial ဖန္ရွင္ကိုေကာ္ျပန္ေခၚတယ္ ။ 3>1 ဆိုၿပိးစစ္တယ္ ။ ႀကီးေနေသးတယ္ အဲဒီေတာ႔ 4*3*factorial(2) ဆိုတဲ႔ပံုစံျဖစ္သြားတယ္ ။ ဖန္ရွင္ေကာျပန္ေခၚတယ္ ။ 2>1 ဆိုၿပိးစစ္တယ္ ႀကိးေနေသးေတာ႔ 4*3*2*factorial(1) ပံုစံျဖစ္တယ္ ။
1>1 ဆိုၿပီးစစ္တယ္ ။ အဲဒီေတာ႔ မႀကီးေတာ႔ဘူး မႀကိးေတာ႔ loop ကေနရပ္သြားတယ္ ။ ဒါေၾကာင္႔ 4 ! = 4*3*2 =24 ဆိုၿပီးအေျဖထုတ္ေပးတာပါ ။ 4 ထည့္ထားတဲ႔ Result ကိုၾကည့္ၾကည့္ပါ ။

Result




Function အေၾကာင္းမွာဒီေလာက္ဆိုရင္ ေတာ္ေတာ္ေလးလံုေလာက္မယ္ထင္ပါတယ္ ။ ကၽြန္ေတာ္ မေဆြးေႏြးပဲက်န္ေနတာေတြလည္းရွိနိင္ပါေသးတယ္ ။ ဖန္ရွင္နဲ႔ပက္သက္ၿပီး program code ေလးေတြထပ္မံေလံလာခ်င္ေသးတယ္ဆိုရင္ေတာ႔
http://www.java2s.com/Tutorial/Cpp/0140__Function/Catalog0140__Function.htm မွာ ကိုယ္တိုင္သြားၿပီးေလ႔လာနိုင္ပါတယ္ ။ ကၽြန္ေတာ္ေဆြးေႏြးထားတဲ႔သီအိုရီေတြနဲ႔ ေပးထားတ႔ဲလင္႔ခ္က ကုဒ္ေလးေတြ တြဲၿပီး ေလ႔လာမယ္ဆိုရင္ ပိုၿပီးနားလည္မွာပါ ။ အားလံုးပဲအဆင္ေျပၾကပါေစ ။

0 comments:

Post a Comment

ဒီPost ရဲ႕ေရးသားခ်က္နဲ႕ပက္သက္ျပီး ေ၀ဖန္အၾကံျပဳႏုိင္ပါတယ္။