C++ Function Pointers: Functions में Arguments Pass करने के तीन तरीके हैं।
- Pass By Value / Call by Value
- Pass By Reference / Call by Reference
- Pass By Pointer or Pass By Address / Call by Pointer or Call by Address
जब हमें किसी Program में किसी Variable के Actual मान पर किसी प्रकार का Operation Perform करना होता है, तब हम उस Variable को Function में By Value Pass नहीं कर सकते हैं। क्योंकि ऐसा करने पर Function केवल उस Variable के मान की एक Copy को प्राप्त करता है, Actual Variable को नहीं। लेकिन Variable को By Reference या By Pointer Function में Pass करके हम Variable के Actual मानों पर Operation Perform करवा सकते हैं।
चलिए, सबसे पहले हम एक Code Segment देखते हैं, जिसके आधार पर ये समझा जा सके कि Function में Arguments को By Reference किस प्रकार से भेजा जाता है। Code Segment निम्नानुसार है:
void main() { void centimize(double&); // prototype double var = 10.0; // var has value of 10 inches cout << endl << “var=” << var << “ inches"; centimize(var); // change var to centimeters cout << endl << “var=” << var << “ centimeters"; } void centimize(double& v) { v *= 2.54; // v is the same as var }
इस Code Segment में हम main() Function में एक Variable var के मान को inches से centimeters में Convert करना चाहते हैं। हमने Variable को centimize() Function में By Reference Pass किया है। ध्यान रहे कि Prototype में Data Type के बाद & का प्रयोग करने का मतलब है कि हम Argument को By Reference function में Pass करेंगे। centimize() Function Variable के Original मान को 2.54 से गुणा करता है। ध्यान दें कि Function Variable को किस प्रकार से Refer कर रहा है। ये बिल्कुल सामान्य तरीके से Variable के नाम v को Use कर रहा है। v और var एक ही Variable के दो अलग नाम हैं। एक बार Variable का मान Centimeters में Convert हो जाता है, तो main() Function इस Variable के मान को Output में निम्नानुसार Display कर देता है:
Var = 25.4 centimeters
इसी काम को हम Pointers द्वारा निम्नानुसार तरीके से कर सकते हैं:
void main() { void centimize(double*); // prototype double var = 10.0; // var has value of 10 inches cout << endl << “var=” << var << “ inches"; centimize(&var); // change var to centimeters cout << endl << “var=” << var << “ centimeters"; } void centimize(double* ptrd) { *ptrd *= 2.54; // *ptrd is the same as var }
इन दोनों Programs का Output एक समान ही प्राप्त होता है। main() Function में centimize() Function को इस प्रकार Declare किया गया है कि वह Argument के रूप में एक double प्रकार का Pointer लेता है यानी ये Pointer to double प्रकार का Argument Accept करता है।
void centimize(double*); <==== argument is a pointer to double
जब main() Function इस Function को Call करता है, तो उसे Variable var का Address Argument के रूप में Pass करता है। यानी:
centimize(&var);
ध्यान दें कि इस Function में Variable var का Address भेजा जा रहा है ना कि स्वयं Variable को] जैसाकि Pass By Reference में किया जाता है। चूंकि Function में Argument को By Address या By Pointer भेजा जा रहा है, इसलिए इस Variable के मान को Access करने के लिए Function में Indirection Operator का प्रयोग किया गया है। यानी:
*ptrd *= 2.54;
इस Statement को हम निम्नानुसार भी लिख सकते हैं:
*prtd = *ptrd * 2.54;
चूंकि, ptrd में Actual Argument का Address है, इसलिए इस Pointer Variable के साथ जो भी Operation Perform किया जाता है, उस Operation का प्रभाव सीधे main() Function के Variable var पर होता है और *ptrd का मान Function में Change होने पर Calling Function main() में भी var का मान Change हो जाता है।
किसी Function में By Reference Argument Pass करने का तरीका कुछ हद तक वही होता है जो किसी Pointer को Pass करने का होता है। ये दोनों ही Passing तरीके Calling Function के Variable के मान को Change करने की सुविधा Called Function को देते हैं। फिर भी दोनों के काम करने का तरीका अलग है। किसी Variable का Reference उस Variable का एक Alias या दूसरा नाम होता है जबकि किसी Variable का Pointer उस Variable का Address होता है।
हम जानते हैं कि एक Array को किसी Function में किसी प्रकार से Pass किया जा सकता है और Array के Elements को Function द्वारा Access किया जा सकता है। पिछले अध्यायों में ये काम Array Notation द्वारा किया गया था। लेकिन जब किसी Array को किसी Function में Pass करना होता है, तब Array Notation के बजाय Pointer Notation का प्रयोग करके Array को Function में Pass करना काफी सुविधाजनक होता है। इसे हम निम्न Code Segment द्वारा Represent कर सकते हैं:
const int MAX = 5; // number of array elements void main() { void centimize(double*); // prototype double vArray[MAX] = { 10.0, 43.1, 95.9, 59.7, 87.3 }; centimize(vArray); // change elements of vArray to cm for(int j=0; j<MAX; j++) // display new array values cout << endl << “vArray[” << j << “]=”<< vArray[j] << “ centimeters"; } void centimize(double* ptrd) { for(int j=0; j<MAX; j++) *ptrd++ *= 2.54; // ptrd points to elements of vArray }
हम देख सकते हैं कि दोनों ही उदाहरणों में Function का Prototype एक समान है यानी Argument के रूप में Function एक Pointer to double प्रकार का Argument लेता है। इसे Array Notation में निम्नानुसार लिखा जा सकता है:
void centimize(double[]);
यानी Pointer Notation का double* व Array Notation का double[] एक समान हैं, लेकिन Pointer Notation का प्रयोग अधिक किया जाता है। क्योंकि Array का नाम Array का Address होता है, इसलिए Function को Call करते समय Address Operator & के प्रयोग की जरूरत नहीं पडती है। यानी हम Array को इस प्रकार के Function में निम्नानुसार As a Argument Pass कर सकते हैं:
centimize(vArray); //Passing Array’s Address to Function
इस तरह से Function को Call करने पर centimize() Function में Array का Address ptrd Pointer Variable में Store हो जाता है और Array के हर Element को Access करने के लिए हमें केवल ptrd को Increment करना होता है। यानी
*ptrd++ *= 2.54;
इन दोनों उदाहरणों का Output निम्नानुसार एक समान प्राप्त होता है:
vArray[0]=25.4 centimeters
vArray[1]=109.474 centimeters
vArray[2]=243.586 centimeters
vArray[3]=151.638 centimeters
vArray[4]=221.742 centimeters
यहां एक Syntax का सवाल पैदा होता है कि हमें ये कैसे पता चलेगा कि *ptrd++ Expression Pointer को Increment कर रहा है ना कि Pointer के Content को ?
दूसरे शब्दों में कहें तो क्या Compiler इस Expression को *(ptrd++) की तरह से Access करके हमें हमारा परिणाम प्रदान करता है जिसमें पहले Pointer Increment होता है या (*ptrd)++ Expression से हमें हमारा परिणाम प्रदान करता है जिसमें पहले Element का मान Return होता है, फिर Pointer Increment होता है।
चूंकि Indirection Operator ( * ) व Increment Operator (++) इन दोनों का प्राथमिकता क्रम एक समान है। इसलिए जब इस प्रकार की स्थिति होती है तो Compiler समान प्राथमिकता वाले Operators एक दूसरे तरीके Associativity के आधार पर Handle करता है। जहां Associativity इस बात पर आधारित होती है कि Compiler Expression को Left to Right Side में Perform करना शुरू कर रहा है या Right to Left Side में।
जब Operators के एक Group की Associativity Left to Right होती है, तब Compiler Expression को Left से Perform करना शुरू करता है और जब Operators के एक Group की Associativity Right to Left होती है, तब Compiler Expression को Right से Perform करना शुरू करता है और Left तक पहुंचता है।
Unary Operator * व ++ दोनों की Associativity Right to Left है, इसलिए Expression *(ptrd++) के Form में Interpreted होता है जो Pointer को Increment करता है ना कि उस मान को जिसे Pointer Point कर रहा है। इसी वजह से Pointer पहले Increment होता है फिर उस पर Indirection Operator Apply होता है। (C++ Function Pointers – WikiBooks)
ये Article इस वेबसाईट पर Selling हेतु उपलब्ध EBook C++ Programming Language in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी।
C++ Programming Language in Hindi | Page: 666 | Format: PDF