फंक्शन पॉइंटर: Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
{{short description|Pointer that points to a function}} | {{short description|Pointer that points to a function}} | ||
{{Use American English|date=July 2022}} | {{Use American English|date=July 2022}} | ||
एक फ़ंक्शन पॉइंटर, जिसे [[सबरूटीन]] पॉइंटर या प्रोसेस पॉइंटर भी कहा जाता है, | एक फ़ंक्शन पॉइंटर, जिसे [[सबरूटीन]] पॉइंटर या प्रोसेस पॉइंटर भी कहा जाता है, [[सूचक (कंप्यूटर प्रोग्रामिंग)]] है जो किसी फ़ंक्शन को इंगित करता है। डेटा मान को संदर्भित करने के विरोध में, फ़ंक्शन पॉइंटर स्मृति के अंदर निष्पादन योग्य कोड को इंगित करता है। [[डेरेफरेंस ऑपरेटर]] फ़ंक्शन पॉइंटर संदर्भित सबरूटीन उत्पन्न करता है, जिसे सामान्य फ़ंक्शन कॉल की तरह ही प्रयुक्त किया जा सकता है और तर्क पारित किया जा सकता है। इस तरह के आह्वान को अप्रत्यक्ष कॉल के रूप में भी जाना जाता है, क्योंकि निश्चित पहचानकर्ता या पते के माध्यम से 'सीधे' के अतिरिक्त चर के माध्यम से 'अप्रत्यक्ष रूप से' फ़ंक्शन का आह्वान किया जा रहा है। | ||
फ़ंक्शन पॉइंटर्स का उपयोग रन-टाइम मानों के आधार पर निष्पादित करने के लिए फ़ंक्शन का चयन करने का | फ़ंक्शन पॉइंटर्स का उपयोग रन-टाइम मानों के आधार पर निष्पादित करने के लिए फ़ंक्शन का चयन करने का आसान विधि प्रदान करके कोड को सरल बनाने के लिए किया जा सकता है। | ||
फंक्शन पॉइंटर्स [[तीसरी पीढ़ी की [[प्रोग्रामिंग भाषा]]]] द्वारा समर्थित हैं | तीसरी पीढ़ी की प्रोग्रामिंग भाषाएँ (जैसे PL/I, [[COBOL]], [[फोरट्रान]],<ref>{{cite web|url=http://www.esm.psu.edu/~ajm138/fortranexamples.html#ex1|title=Fortran Examples|author=Andrew J. Miller|access-date=2013-09-14}}</ref> dBASE dBL, और C (प्रोग्रामिंग लैंग्वेज)) और [[ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग]] लैंग्वेज (जैसे C ++, C Sharp (प्रोग्रामिंग लैंग्वेज) | C #, और D (प्रोग्रामिंग लैंग्वेज))।<ref>{{cite web|url=http://www.newty.de/fpt/intro.html#what|title=The Function Pointer Tutorials|publisher=logo|access-date=2011-04-13|quote=Function Pointers are pointers, i.e. variables, which point to the address of a function}}</ref> | फंक्शन पॉइंटर्स [[तीसरी पीढ़ी की [[प्रोग्रामिंग भाषा]]]] द्वारा समर्थित हैं | तीसरी पीढ़ी की प्रोग्रामिंग भाषाएँ (जैसे PL/I, [[COBOL]], [[फोरट्रान]],<ref>{{cite web|url=http://www.esm.psu.edu/~ajm138/fortranexamples.html#ex1|title=Fortran Examples|author=Andrew J. Miller|access-date=2013-09-14}}</ref> dBASE dBL, और C (प्रोग्रामिंग लैंग्वेज)) और [[ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग]] लैंग्वेज (जैसे C ++, C Sharp (प्रोग्रामिंग लैंग्वेज) | C #, और D (प्रोग्रामिंग लैंग्वेज))।<ref>{{cite web|url=http://www.newty.de/fpt/intro.html#what|title=The Function Pointer Tutorials|publisher=logo|access-date=2011-04-13|quote=Function Pointers are pointers, i.e. variables, which point to the address of a function}}</ref> | ||
Line 9: | Line 9: | ||
== सरल फ़ंक्शन पॉइंटर्स == | == सरल फ़ंक्शन पॉइंटर्स == | ||
एक फ़ंक्शन (या सबरूटीन) सूचक का सरलतम कार्यान्वयन | एक फ़ंक्शन (या सबरूटीन) सूचक का सरलतम कार्यान्वयन [[चर (कंप्यूटर विज्ञान)]] के रूप में होता है जिसमें निष्पादन योग्य मेमोरी के अंदर फ़ंक्शन का मेमोरी पता होता है। पुरानी तीसरी पीढ़ी की प्रोग्रामिंग भाषा | तीसरी पीढ़ी की भाषाएँ जैसे PL/I और COBOL, साथ ही अधिक आधुनिक भाषाएँ जैसे [[पास्कल (प्रोग्रामिंग भाषा)]] और C (प्रोग्रामिंग भाषा) सामान्यतः इस तरह से फ़ंक्शन पॉइंटर्स को प्रयुक्त करती हैं।<ref>{{cite web | ||
| access-date = 2011-04-13 | | access-date = 2011-04-13 | ||
| publisher = logo | | publisher = logo | ||
Line 20: | Line 20: | ||
{{See also|#Alternate C and C++ syntax}} | {{See also|#Alternate C and C++ syntax}} | ||
निम्नलिखित सी प्रोग्राम दो फ़ंक्शन पॉइंटर्स के उपयोग को दिखाता है: | निम्नलिखित सी प्रोग्राम दो फ़ंक्शन पॉइंटर्स के उपयोग को दिखाता है: | ||
* func1 एक डबल-सटीक (डबल) पैरामीटर लेता है और दूसरा डबल देता है, और | * func1 एक डबल-सटीक (डबल) पैरामीटर लेता है और दूसरा डबल देता है, और फ़ंक्शन को असाइन किया जाता है जो सेंटीमीटर को इंच में परिवर्तित करता है। | ||
* func2 | * func2 निरंतर वर्ण सरणी के साथ-साथ पूर्णांक के लिए सूचक लेता है और वर्ण को सूचक देता है, और एक C स्ट्रिंग हैंडलिंग फ़ंक्शन को सौंपा जाता है जो किसी वर्ण सरणी में दिए गए वर्ण की पहली घटना के लिए सूचक देता है। | ||
<वाक्यविन्यास प्रकाश लैंग = सी> | <वाक्यविन्यास प्रकाश लैंग = सी> | ||
Line 43: | Line 43: | ||
</वाक्यविन्यास हाइलाइट> | </वाक्यविन्यास हाइलाइट> | ||
अगला प्रोग्राम दो कार्यों में से एक को प्रयुक्त करने के लिए फ़ंक्शन पॉइंटर का उपयोग करता है (<code>sin</code> या <code>cos</code>) अप्रत्यक्ष रूप से किसी अन्य फ़ंक्शन से (<code>compute_sum</code>, फ़ंक्शन के रिमेंन एकीकरण के | अगला प्रोग्राम दो कार्यों में से एक को प्रयुक्त करने के लिए फ़ंक्शन पॉइंटर का उपयोग करता है (<code>sin</code> या <code>cos</code>) अप्रत्यक्ष रूप से किसी अन्य फ़ंक्शन से (<code>compute_sum</code>, फ़ंक्शन के रिमेंन एकीकरण के अनुमान की गणना)। कार्यक्रम कार्य करके संचालित होता है <code>main</code> कॉल समारोह <code>compute_sum</code> दो बार, इसे लाइब्रेरी फ़ंक्शन के लिए पॉइंटर पास करना <code>sin</code> पहली बार, और कार्य करने के लिए सूचक <code>cos</code> सेकंड समय। समारोह <code>compute_sum</code> बदले में अपने फ़ंक्शन पॉइंटर तर्क को संदर्भित करके अप्रत्यक्ष रूप से दो कार्यों में से एक को आमंत्रित करता है <code>funcp</code> कई बार, उन मानों को साथ जोड़कर जो इनवोक किए गए फ़ंक्शन लौटाते हैं और परिणामी राशि लौटाते हैं। दो राशियों को मानक आउटपुट द्वारा लिखा जाता है <code>main</code>. | ||
<वाक्यविन्यास लैंग = सी लाइन = 1> | <वाक्यविन्यास लैंग = सी लाइन = 1> | ||
Line 49: | Line 49: | ||
#सम्मिलित <stdio.h> | #सम्मिलित <stdio.h> | ||
// फंक्शन | // फंक्शन तर्क के रूप में फ़ंक्शन पॉइंटर लेता है | ||
डबल कंप्यूट_सम (डबल (* funcp) (डबल), डबल लो, डबल हाय) { | डबल कंप्यूट_सम (डबल (* funcp) (डबल), डबल लो, डबल हाय) { | ||
दोहरा योग = 0.0; | दोहरा योग = 0.0; | ||
Line 89: | Line 89: | ||
== फंक्टर्स == | == फंक्टर्स == | ||
{{main|Function object}} | {{main|Function object}} | ||
फ़ंक्टर, या फ़ंक्शन ऑब्जेक्ट, फ़ंक्शन पॉइंटर्स के समान हैं, और समान तरीकों से उपयोग किए जा सकते हैं। | फ़ंक्टर, या फ़ंक्शन ऑब्जेक्ट, फ़ंक्शन पॉइंटर्स के समान हैं, और समान तरीकों से उपयोग किए जा सकते हैं। फ़ंक्टर वर्ग प्रकार का ऑब्जेक्ट है जो [[फ़ंक्शन-कॉल ऑपरेटर]] को प्रयुक्त करता है, ऑब्जेक्ट को फ़ंक्शन कॉल के समान सिंटैक्स का उपयोग करके एक्सप्रेशन के अंदर उपयोग करने की अनुमति देता है। फ़ंक्टर साधारण फ़ंक्शन पॉइंटर्स की तुलना में अधिक शक्तिशाली होते हैं, अपने स्वयं के डेटा मान रखने में सक्षम होते हैं, और प्रोग्रामर को [[क्लोजर (कंप्यूटर प्रोग्रामिंग)]] का अनुकरण करने की अनुमति देते हैं। कॉलबैक फ़ंक्शन के रूप में सदस्य फ़ंक्शन का उपयोग करना आवश्यक होने पर उन्हें कॉलबैक फ़ंक्शन के रूप में भी उपयोग किया जाता है।<ref>{{cite web | ||
| access-date = 2011-04-13 | | access-date = 2011-04-13 | ||
| date = 2005-01-31 | | date = 2005-01-31 | ||
Line 100: | Line 100: | ||
अन्य भाषाओं में जो प्रथम श्रेणी के कार्यों का समर्थन करते हैं, कार्यों को डेटा के रूप में माना जाता है, और फ़ंक्शन पॉइंटर्स की आवश्यकता को समाप्त करते हुए, अन्य कार्यों द्वारा सीधे पारित किया जा सकता है, लौटाया जा सकता है और गतिशील रूप से बनाया जा सकता है। | अन्य भाषाओं में जो प्रथम श्रेणी के कार्यों का समर्थन करते हैं, कार्यों को डेटा के रूप में माना जाता है, और फ़ंक्शन पॉइंटर्स की आवश्यकता को समाप्त करते हुए, अन्य कार्यों द्वारा सीधे पारित किया जा सकता है, लौटाया जा सकता है और गतिशील रूप से बनाया जा सकता है। | ||
कार्यों को कॉल करने के लिए फ़ंक्शन पॉइंटर्स का व्यापक रूप से उपयोग आधुनिक प्रोसेसर पर कोड के लिए धीमा हो सकता है, क्योंकि | कार्यों को कॉल करने के लिए फ़ंक्शन पॉइंटर्स का व्यापक रूप से उपयोग आधुनिक प्रोसेसर पर कोड के लिए धीमा हो सकता है, क्योंकि [[शाखा भविष्यवक्ता]] यह पता लगाने में सक्षम नहीं हो सकता है कि कहां शाखा करना है (यह रन टाइम पर फ़ंक्शन पॉइंटर के मान पर निर्भर करता है) चूंकि इस प्रभाव को अतिरंजित किया जा सकता है क्योंकि अधिकांशतः गैर-अनुक्रमित तालिका लुकअप को अधिक कम करके इसकी भरपाई की जाती है। | ||
== विधि संकेत == | == विधि संकेत == | ||
C++ में ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग के लिए समर्थन सम्मिलित है, इसलिए कक्षाओं में विधि (कंप्यूटर प्रोग्रामिंग) हो सकती है (आमतौर पर सदस्य कार्यों के रूप में संदर्भित)। गैर-स्थैतिक सदस्य फ़ंक्शंस (इंस्टेंस मेथड्स) में | C++ में ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग के लिए समर्थन सम्मिलित है, इसलिए कक्षाओं में विधि (कंप्यूटर प्रोग्रामिंग) हो सकती है (आमतौर पर सदस्य कार्यों के रूप में संदर्भित)। गैर-स्थैतिक सदस्य फ़ंक्शंस (इंस्टेंस मेथड्स) में निहित पैरामीटर ([[यह (कंप्यूटर प्रोग्रामिंग)]] पॉइंटर) होता है, जो उस ऑब्जेक्ट के लिए पॉइंटर होता है, जिस पर यह काम कर रहा है, इसलिए ऑब्जेक्ट के प्रकार को प्रकार के हिस्से के रूप में सम्मिलित किया जाना चाहिए। समारोह सूचक। विधि का उपयोग उस वर्ग के ऑब्जेक्ट पर पॉइंटर-टू-सदस्य ऑपरेटरों में से एक का उपयोग करके किया जाता है: <code>.*</code> या <code>->*</code> (किसी वस्तु या वस्तु के सूचक के लिए क्रमशः)।{{Dubious|date=December 2022}} | ||
चूंकि सी और सी ++ में फ़ंक्शन पॉइंटर्स को साधारण पते के रूप में प्रयुक्त किया जा सकता है, जिससेसामान्यतः <code>sizeof(Fx)==sizeof(void *)</code>, सी ++ में सदस्य पॉइंटर्स को कभी-कभी वसा पॉइंटर्स के रूप में कार्यान्वित किया जाता है, आमतौर पर वर्चुअल विधियों और वर्चुअल विरासत से निपटने के लिए | चूंकि सी और सी ++ में फ़ंक्शन पॉइंटर्स को साधारण पते के रूप में प्रयुक्त किया जा सकता है, जिससेसामान्यतः <code>sizeof(Fx)==sizeof(void *)</code>, सी ++ में सदस्य पॉइंटर्स को कभी-कभी वसा पॉइंटर्स के रूप में कार्यान्वित किया जाता है, आमतौर पर वर्चुअल विधियों और वर्चुअल विरासत से निपटने के लिए साधारण फ़ंक्शन पॉइंटर के आकार के दो या तीन गुना{{Citation needed|date=August 2011}}. | ||
== सी ++ == में | == सी ++ == में | ||
Line 179: | Line 179: | ||
== वैकल्पिक सी और सी ++ सिंटैक्स == | == वैकल्पिक सी और सी ++ सिंटैक्स == | ||
ऊपर दिया गया C और C++ सिंटैक्स सभी पाठ्य पुस्तकों में उपयोग किया जाने वाला विहित सिंटैक्स है - किन्तुइसे पढ़ना और समझाना जटिल है। ऊपर वाला भी <code>typedef</code> उदाहरण इस सिंटैक्स का उपयोग करते हैं। चूंकि, प्रत्येक सी और सी ++ कंपाइलर फ़ंक्शन पॉइंटर्स घोषित करने के लिए | ऊपर दिया गया C और C++ सिंटैक्स सभी पाठ्य पुस्तकों में उपयोग किया जाने वाला विहित सिंटैक्स है - किन्तुइसे पढ़ना और समझाना जटिल है। ऊपर वाला भी <code>typedef</code> उदाहरण इस सिंटैक्स का उपयोग करते हैं। चूंकि, प्रत्येक सी और सी ++ कंपाइलर फ़ंक्शन पॉइंटर्स घोषित करने के लिए और स्पष्ट और संक्षिप्त तंत्र का समर्थन करता है: उपयोग करें <code>typedef</code>, किन्तुसूचक को परिभाषा के हिस्से के रूप में संग्रहीत न करें। ध्यान दें कि इस तरह का एकमात्र विधि <code>typedef</code> वास्तव में पॉइंटर के साथ उपयोग किया जा सकता है - किन्तुयह इसके पॉइंटर-नेस को हाइलाइट करता है। | ||
=== सी और सी ++ === | === सी और सी ++ === | ||
<वाक्यविन्यास लैंग = सी> | <वाक्यविन्यास लैंग = सी> | ||
// यह 'एफ' की घोषणा करता है, | // यह 'एफ' की घोषणा करता है, ऐसा कार्य जो 'चार' को स्वीकार करता है और 'इंट' लौटाता है। परिभाषा कहीं और है। | ||
इंट एफ (चार सी); | इंट एफ (चार सी); | ||
// यह 'एफएन' को परिभाषित करता है, | // यह 'एफएन' को परिभाषित करता है, प्रकार का फ़ंक्शन जो 'चार' स्वीकार करता है और 'इंट' देता है। | ||
टाइपपीफ इंट एफएन (चार सी); | टाइपपीफ इंट एफएन (चार सी); | ||
// यह 'एफएन' को परिभाषित करता है, टाइप पॉइंटर-टू-'एफएन' का | // यह 'एफएन' को परिभाषित करता है, टाइप पॉइंटर-टू-'एफएन' का चर, और इसे 'एफ' का पता निर्दिष्ट करता है। | ||
एफएन *एफएन = और एफ; // नोट 'और' की आवश्यकता नहीं है - किन्तुयह हाइलाइट करता है कि क्या किया जा रहा है। | एफएन *एफएन = और एफ; // नोट 'और' की आवश्यकता नहीं है - किन्तुयह हाइलाइट करता है कि क्या किया जा रहा है। | ||
Line 195: | Line 195: | ||
इंट ए = एफएन ('ए'); | इंट ए = एफएन ('ए'); | ||
// यह 'कॉल' को परिभाषित करता है, | // यह 'कॉल' को परिभाषित करता है, ऐसा फ़ंक्शन जो पॉइंटर-टू-'एफएन' स्वीकार करता है, इसे कॉल करता है, और परिणाम देता है | ||
इंट कॉल (एफएन * एफएन, चार सी) { | इंट कॉल (एफएन * एफएन, चार सी) { | ||
वापसी एफएन (सी); | वापसी एफएन (सी); | ||
Line 217: | Line 217: | ||
ये उदाहरण उपरोक्त परिभाषाओं का उपयोग करते हैं। विशेष रूप से, ध्यान दें कि उपरोक्त परिभाषा के लिए <code>Fn</code> पॉइंटर-टू-सदस्य-फ़ंक्शन परिभाषाओं में उपयोग किया जा सकता है: | ये उदाहरण उपरोक्त परिभाषाओं का उपयोग करते हैं। विशेष रूप से, ध्यान दें कि उपरोक्त परिभाषा के लिए <code>Fn</code> पॉइंटर-टू-सदस्य-फ़ंक्शन परिभाषाओं में उपयोग किया जा सकता है: | ||
<वाक्यविन्यास लैंग = सीपीपी> | <वाक्यविन्यास लैंग = सीपीपी> | ||
// यह 'सी' को परिभाषित करता है, समान स्थिर और सदस्य कार्यों वाला | // यह 'सी' को परिभाषित करता है, समान स्थिर और सदस्य कार्यों वाला वर्ग, | ||
// और फिर 'सी' नामक | // और फिर 'सी' नामक उदाहरण बनाता है | ||
कक्षा सी { | कक्षा सी { | ||
जनता: | जनता: | ||
Line 232: | Line 232: | ||
एफएन = और सी :: स्टेटिक; | एफएन = और सी :: स्टेटिक; | ||
// यह 'एम' को परिभाषित करता है, | // यह 'एम' को परिभाषित करता है, पॉइंटर-टू-मेंबर-ऑफ-'सी' टाइप 'एफएन' के साथ, | ||
// और इसे 'सी :: सदस्य' का पता निर्दिष्ट करता है। | // और इसे 'सी :: सदस्य' का पता निर्दिष्ट करता है। | ||
// आप इसे सभी पॉइंटर्स की तरह राइट-टू-लेफ्ट पढ़ सकते हैं: | // आप इसे सभी पॉइंटर्स की तरह राइट-टू-लेफ्ट पढ़ सकते हैं: | ||
Line 244: | Line 244: | ||
int pA = (p->*m)('A'); | int pA = (p->*m)('A'); | ||
// यह 'रेफरी' को परिभाषित करता है, | // यह 'रेफरी' को परिभाषित करता है, ऐसा फ़ंक्शन जो संदर्भ-से-'सी' स्वीकार करता है, | ||
// | // पॉइंटर-टू-मेंबर-ऑफ-'C' टाइप 'Fn', और 'char', | ||
// फ़ंक्शन को कॉल करें और परिणाम लौटाएं | // फ़ंक्शन को कॉल करें और परिणाम लौटाएं | ||
इंट रेफ (सी एंड आर, एफएन सी :: * एम, चार सी) { | इंट रेफ (सी एंड आर, एफएन सी :: * एम, चार सी) { | ||
Line 251: | Line 251: | ||
} // संदर्भ (आर, एम, सी) | } // संदर्भ (आर, एम, सी) | ||
// यह 'Ptr' को परिभाषित करता है, | // यह 'Ptr' को परिभाषित करता है, ऐसा फंक्शन जो पॉइंटर-टू-'C' को स्वीकार करता है, | ||
// | // पॉइंटर-टू-मेंबर-ऑफ-'C' टाइप 'Fn', और 'char', | ||
// फ़ंक्शन को कॉल करें और परिणाम लौटाएं | // फ़ंक्शन को कॉल करें और परिणाम लौटाएं | ||
इंट पीआरटी (सी * पी, एफएन सी :: * एम, चार सी) { | इंट पीआरटी (सी * पी, एफएन सी :: * एम, चार सी) { |
Revision as of 13:06, 4 March 2023
एक फ़ंक्शन पॉइंटर, जिसे सबरूटीन पॉइंटर या प्रोसेस पॉइंटर भी कहा जाता है, सूचक (कंप्यूटर प्रोग्रामिंग) है जो किसी फ़ंक्शन को इंगित करता है। डेटा मान को संदर्भित करने के विरोध में, फ़ंक्शन पॉइंटर स्मृति के अंदर निष्पादन योग्य कोड को इंगित करता है। डेरेफरेंस ऑपरेटर फ़ंक्शन पॉइंटर संदर्भित सबरूटीन उत्पन्न करता है, जिसे सामान्य फ़ंक्शन कॉल की तरह ही प्रयुक्त किया जा सकता है और तर्क पारित किया जा सकता है। इस तरह के आह्वान को अप्रत्यक्ष कॉल के रूप में भी जाना जाता है, क्योंकि निश्चित पहचानकर्ता या पते के माध्यम से 'सीधे' के अतिरिक्त चर के माध्यम से 'अप्रत्यक्ष रूप से' फ़ंक्शन का आह्वान किया जा रहा है।
फ़ंक्शन पॉइंटर्स का उपयोग रन-टाइम मानों के आधार पर निष्पादित करने के लिए फ़ंक्शन का चयन करने का आसान विधि प्रदान करके कोड को सरल बनाने के लिए किया जा सकता है।
फंक्शन पॉइंटर्स [[तीसरी पीढ़ी की प्रोग्रामिंग भाषा]] द्वारा समर्थित हैं | तीसरी पीढ़ी की प्रोग्रामिंग भाषाएँ (जैसे PL/I, COBOL, फोरट्रान,[1] dBASE dBL, और C (प्रोग्रामिंग लैंग्वेज)) और ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग लैंग्वेज (जैसे C ++, C Sharp (प्रोग्रामिंग लैंग्वेज) | C #, और D (प्रोग्रामिंग लैंग्वेज))।[2]
सरल फ़ंक्शन पॉइंटर्स
एक फ़ंक्शन (या सबरूटीन) सूचक का सरलतम कार्यान्वयन चर (कंप्यूटर विज्ञान) के रूप में होता है जिसमें निष्पादन योग्य मेमोरी के अंदर फ़ंक्शन का मेमोरी पता होता है। पुरानी तीसरी पीढ़ी की प्रोग्रामिंग भाषा | तीसरी पीढ़ी की भाषाएँ जैसे PL/I और COBOL, साथ ही अधिक आधुनिक भाषाएँ जैसे पास्कल (प्रोग्रामिंग भाषा) और C (प्रोग्रामिंग भाषा) सामान्यतः इस तरह से फ़ंक्शन पॉइंटर्स को प्रयुक्त करती हैं।[3]
=== सी === में उदाहरण
निम्नलिखित सी प्रोग्राम दो फ़ंक्शन पॉइंटर्स के उपयोग को दिखाता है:
- func1 एक डबल-सटीक (डबल) पैरामीटर लेता है और दूसरा डबल देता है, और फ़ंक्शन को असाइन किया जाता है जो सेंटीमीटर को इंच में परिवर्तित करता है।
- func2 निरंतर वर्ण सरणी के साथ-साथ पूर्णांक के लिए सूचक लेता है और वर्ण को सूचक देता है, और एक C स्ट्रिंग हैंडलिंग फ़ंक्शन को सौंपा जाता है जो किसी वर्ण सरणी में दिए गए वर्ण की पहली घटना के लिए सूचक देता है।
<वाक्यविन्यास प्रकाश लैंग = सी>
- include <stdio.h> /* प्रिंटफ के लिए */
- include <string.h> /* strchr के लिए */
डबल सेमी_टू_इंच (डबल सेमी) { वापसी सेमी / 2.54; }
// strchr सी स्ट्रिंग हैंडलिंग का हिस्सा है (अर्थात, घोषणा की कोई आवश्यकता नहीं है) // https://en.wikipedia.org/wiki/C_string_handling#Functions देखें
पूर्णांक मुख्य (शून्य) { डबल (*func1)(डबल) = cm_to_inches; चार * (* func2) (स्थिरांक चार *, int) = strchr; प्रिंटफ (% f% s, func1 (15.0), func2 (विकिपीडिया, 'पी')); /* 5.905512 पीडिया प्रिंट करता है */ वापसी 0; } </वाक्यविन्यास हाइलाइट>
अगला प्रोग्राम दो कार्यों में से एक को प्रयुक्त करने के लिए फ़ंक्शन पॉइंटर का उपयोग करता है (sin
या cos
) अप्रत्यक्ष रूप से किसी अन्य फ़ंक्शन से (compute_sum
, फ़ंक्शन के रिमेंन एकीकरण के अनुमान की गणना)। कार्यक्रम कार्य करके संचालित होता है main
कॉल समारोह compute_sum
दो बार, इसे लाइब्रेरी फ़ंक्शन के लिए पॉइंटर पास करना sin
पहली बार, और कार्य करने के लिए सूचक cos
सेकंड समय। समारोह compute_sum
बदले में अपने फ़ंक्शन पॉइंटर तर्क को संदर्भित करके अप्रत्यक्ष रूप से दो कार्यों में से एक को आमंत्रित करता है funcp
कई बार, उन मानों को साथ जोड़कर जो इनवोक किए गए फ़ंक्शन लौटाते हैं और परिणामी राशि लौटाते हैं। दो राशियों को मानक आउटपुट द्वारा लिखा जाता है main
.
<वाक्यविन्यास लैंग = सी लाइन = 1>
- सम्मिलित <गणित.एच>
- सम्मिलित <stdio.h>
// फंक्शन तर्क के रूप में फ़ंक्शन पॉइंटर लेता है डबल कंप्यूट_सम (डबल (* funcp) (डबल), डबल लो, डबल हाय) {
दोहरा योग = 0.0;
// पॉइंट-टू-फ़ंक्शन '*funcp' द्वारा लौटाए गए मान जोड़ें int मैं; के लिए (i = 0; i <= 100; i++) { // फ़ंक्शन का आह्वान करने के लिए फ़ंक्शन पॉइंटर 'funcp' का उपयोग करें डबल एक्स = आई / 100.0 * (हाय - लो) + लो; डबल वाई = funcp (एक्स); योग + = वाई; } वापसी राशि / 101.0 * (हाय - लो);
}
डबल स्क्वायर (डबल एक्स) {
वापसी एक्स * एक्स;
}
पूर्णांक मुख्य (शून्य) {
दोहरी राशि;
// पॉइंट-टू-फ़ंक्शन के रूप में मानक लाइब्रेरी फ़ंक्शन 'sin ()' का उपयोग करें योग = कंप्यूट_सम (पाप, 0.0, 1.0); प्रिंटफ (योग (पाप):% जी \ n, योग);
// पॉइंट-टू-फ़ंक्शन के रूप में मानक लाइब्रेरी फ़ंक्शन 'cos ()' का उपयोग करें योग = कंप्यूट_सम (कॉस, 0.0, 1.0); प्रिंटफ (योग (cos):% g \ n, योग);
// यूजर-डिफ़ाइंड फ़ंक्शन 'स्क्वायर ()' को पॉइंट-टू-फ़ंक्शन के रूप में उपयोग करें योग = कंप्यूट_सम (वर्ग, 0.0, 1.0); प्रिंटफ (योग (वर्ग):% जी \ n, योग);
वापसी 0;
} </वाक्यविन्यास हाइलाइट>
फंक्टर्स
फ़ंक्टर, या फ़ंक्शन ऑब्जेक्ट, फ़ंक्शन पॉइंटर्स के समान हैं, और समान तरीकों से उपयोग किए जा सकते हैं। फ़ंक्टर वर्ग प्रकार का ऑब्जेक्ट है जो फ़ंक्शन-कॉल ऑपरेटर को प्रयुक्त करता है, ऑब्जेक्ट को फ़ंक्शन कॉल के समान सिंटैक्स का उपयोग करके एक्सप्रेशन के अंदर उपयोग करने की अनुमति देता है। फ़ंक्टर साधारण फ़ंक्शन पॉइंटर्स की तुलना में अधिक शक्तिशाली होते हैं, अपने स्वयं के डेटा मान रखने में सक्षम होते हैं, और प्रोग्रामर को क्लोजर (कंप्यूटर प्रोग्रामिंग) का अनुकरण करने की अनुमति देते हैं। कॉलबैक फ़ंक्शन के रूप में सदस्य फ़ंक्शन का उपयोग करना आवश्यक होने पर उन्हें कॉलबैक फ़ंक्शन के रूप में भी उपयोग किया जाता है।[4] कई शुद्ध वस्तु-उन्मुख भाषाएँ फ़ंक्शन पॉइंटर्स का समर्थन नहीं करती हैं। इस तरह की भाषाओं में कुछ समान प्रयुक्त किया जा सकता है, चूंकि, प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) के संदर्भ (कंप्यूटर विज्ञान) का उपयोग करके जो एकल विधि (कंप्यूटर प्रोग्रामिंग) (सदस्य फ़ंक्शन) को परिभाषित करता है। सीएलआई भाषाओं की सूची जैसे कि सी शार्प (प्रोग्रामिंग लैंग्वेज)|सी# और विज़ुअल बेसिक .NET इम्प्लीमेंट प्रकार की सुरक्षा|टाइप-सेफ फंक्शन पॉइंटर्स विद डेलिगेट (सीएलआई)।
अन्य भाषाओं में जो प्रथम श्रेणी के कार्यों का समर्थन करते हैं, कार्यों को डेटा के रूप में माना जाता है, और फ़ंक्शन पॉइंटर्स की आवश्यकता को समाप्त करते हुए, अन्य कार्यों द्वारा सीधे पारित किया जा सकता है, लौटाया जा सकता है और गतिशील रूप से बनाया जा सकता है।
कार्यों को कॉल करने के लिए फ़ंक्शन पॉइंटर्स का व्यापक रूप से उपयोग आधुनिक प्रोसेसर पर कोड के लिए धीमा हो सकता है, क्योंकि शाखा भविष्यवक्ता यह पता लगाने में सक्षम नहीं हो सकता है कि कहां शाखा करना है (यह रन टाइम पर फ़ंक्शन पॉइंटर के मान पर निर्भर करता है) चूंकि इस प्रभाव को अतिरंजित किया जा सकता है क्योंकि अधिकांशतः गैर-अनुक्रमित तालिका लुकअप को अधिक कम करके इसकी भरपाई की जाती है।
विधि संकेत
C++ में ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग के लिए समर्थन सम्मिलित है, इसलिए कक्षाओं में विधि (कंप्यूटर प्रोग्रामिंग) हो सकती है (आमतौर पर सदस्य कार्यों के रूप में संदर्भित)। गैर-स्थैतिक सदस्य फ़ंक्शंस (इंस्टेंस मेथड्स) में निहित पैरामीटर (यह (कंप्यूटर प्रोग्रामिंग) पॉइंटर) होता है, जो उस ऑब्जेक्ट के लिए पॉइंटर होता है, जिस पर यह काम कर रहा है, इसलिए ऑब्जेक्ट के प्रकार को प्रकार के हिस्से के रूप में सम्मिलित किया जाना चाहिए। समारोह सूचक। विधि का उपयोग उस वर्ग के ऑब्जेक्ट पर पॉइंटर-टू-सदस्य ऑपरेटरों में से एक का उपयोग करके किया जाता है: .*
या ->*
(किसी वस्तु या वस्तु के सूचक के लिए क्रमशः)।[dubious ]
चूंकि सी और सी ++ में फ़ंक्शन पॉइंटर्स को साधारण पते के रूप में प्रयुक्त किया जा सकता है, जिससेसामान्यतः sizeof(Fx)==sizeof(void *)
, सी ++ में सदस्य पॉइंटर्स को कभी-कभी वसा पॉइंटर्स के रूप में कार्यान्वित किया जाता है, आमतौर पर वर्चुअल विधियों और वर्चुअल विरासत से निपटने के लिए साधारण फ़ंक्शन पॉइंटर के आकार के दो या तीन गुना[citation needed].
== सी ++ == में C++ में, C में उपयोग की जाने वाली विधि के अतिरिक्त, C++ मानक लाइब्रेरी क्लास टेम्पलेट का उपयोग करना भी संभव है std::function, जिनमें से उदाहरण फ़ंक्शन ऑब्जेक्ट हैं:
<वाक्यविन्यास लैंग = सीपीपी>
- सम्मिलित <iostream>
- सम्मिलित <कार्यात्मक>
स्टेटिक डबल डेरिवेटिव (स्थिरांक एसटीडी :: फ़ंक्शन <डबल (डबल)> और एफ, डबल एक्स 0, डबल ईपीएस) {
डबल ईपीएस2 = ईपीएस / 2; डबल लो = x0 - ईपीएस 2; डबल हाई = x0 + ईपीएस2; रिटर्न (एफ(हाय) - एफ(लो)) / ईपीएस;
}
स्टेटिक डबल एफ (डबल एक्स) {
वापसी एक्स * एक्स;
}
मुख्य प्रवेश बिंदु() {
डबल एक्स = 1; std::cout << d/dx(x ^ 2) [@ x = << x << ] = << व्युत्पन्न (f, x, 1e-5) << std::endl; वापसी 0;
} </वाक्यविन्यास हाइलाइट>
=== सी ++ === में सदस्य कार्यों के लिए प
कक्षाओं या स्ट्रक्चर्स के सदस्य कार्यों से निपटने के समयसी ++ फ़ंक्शन पॉइंटर्स का उपयोग करता है। इन्हें ऑब्जेक्ट पॉइंटर या इस कॉल का उपयोग करके बुलाया जाता है। वे इस प्रकार सुरक्षित हैं कि आप उस प्रकार के सूचक का उपयोग करके केवल उस वर्ग (या डेरिवेटिव) के सदस्यों को कॉल कर सकते हैं। यह उदाहरण सादगी के लिए जोड़े गए सदस्य फ़ंक्शन के सूचक के लिए टाइपपीफ के उपयोग को भी प्रदर्शित करता है। स्थैतिक सदस्य कार्यों के लिए फ़ंक्शन पॉइंटर्स पारंपरिक 'सी' शैली में किए जाते हैं क्योंकि इस कॉल के लिए कोई ऑब्जेक्ट पॉइंटर आवश्यक नहीं है।
<वाक्यविन्यास लैंग = सीपीपी>
- सम्मिलित <iostream>
नेमस्पेस एसटीडी का उपयोग करना;
कक्षा फू {
जनता:
इंट ऐड (इंट आई, इंट जे) { वापसी मैं + जे; } इंट मल्टी (इंट आई, इंट जे) { वापसी आई * जे; } स्टेटिक इंट नेगेट (इंट आई) { वापसी -मैं; }
};
int bar1 (int i, int j, Foo* pFoo, int(Foo::*pfn)(int,int)) {
वापसी (पीएफयू -> * पीएफएन) (आई, जे);
}
टाइपपीफ इंट (फू :: * फू_पीएफएन) (इंट, इंट);
int bar2(int i, int j, Foo* pFoo, Foo_pfn pfn) {
वापसी (पीएफयू -> * पीएफएन) (आई, जे);
}
टाइपपीफ इंट (* पीएफएन) (इंट);
इंट बार3(इंट आई, पीएफएन पीएफएन) {
रिटर्न पीएफएन (आई);
}
मुख्य प्रवेश बिंदु() {
फू फू; cout << Foo::add(2,4) = << bar1(2,4, &foo, &Foo::add) << endl; cout << Foo::mult(3,5) = << bar2(3,5, &foo, &Foo::mult) << endl; cout << Foo::negate(6) = << bar3(6, &Foo::negate) << endl; वापसी 0;
} </वाक्यविन्यास हाइलाइट>
वैकल्पिक सी और सी ++ सिंटैक्स
ऊपर दिया गया C और C++ सिंटैक्स सभी पाठ्य पुस्तकों में उपयोग किया जाने वाला विहित सिंटैक्स है - किन्तुइसे पढ़ना और समझाना जटिल है। ऊपर वाला भी typedef
उदाहरण इस सिंटैक्स का उपयोग करते हैं। चूंकि, प्रत्येक सी और सी ++ कंपाइलर फ़ंक्शन पॉइंटर्स घोषित करने के लिए और स्पष्ट और संक्षिप्त तंत्र का समर्थन करता है: उपयोग करें typedef
, किन्तुसूचक को परिभाषा के हिस्से के रूप में संग्रहीत न करें। ध्यान दें कि इस तरह का एकमात्र विधि typedef
वास्तव में पॉइंटर के साथ उपयोग किया जा सकता है - किन्तुयह इसके पॉइंटर-नेस को हाइलाइट करता है।
सी और सी ++
<वाक्यविन्यास लैंग = सी> // यह 'एफ' की घोषणा करता है, ऐसा कार्य जो 'चार' को स्वीकार करता है और 'इंट' लौटाता है। परिभाषा कहीं और है। इंट एफ (चार सी);
// यह 'एफएन' को परिभाषित करता है, प्रकार का फ़ंक्शन जो 'चार' स्वीकार करता है और 'इंट' देता है। टाइपपीफ इंट एफएन (चार सी);
// यह 'एफएन' को परिभाषित करता है, टाइप पॉइंटर-टू-'एफएन' का चर, और इसे 'एफ' का पता निर्दिष्ट करता है। एफएन *एफएन = और एफ; // नोट 'और' की आवश्यकता नहीं है - किन्तुयह हाइलाइट करता है कि क्या किया जा रहा है।
// यह 'fn' का उपयोग करके 'F' को कॉल करता है, परिणाम को 'a' चर के लिए निर्दिष्ट करता है इंट ए = एफएन ('ए');
// यह 'कॉल' को परिभाषित करता है, ऐसा फ़ंक्शन जो पॉइंटर-टू-'एफएन' स्वीकार करता है, इसे कॉल करता है, और परिणाम देता है इंट कॉल (एफएन * एफएन, चार सी) {
वापसी एफएन (सी);
} // कॉल (एफएन, सी)
// यह 'कॉल' फ़ंक्शन को कॉल करता है, 'एफ' में गुजरता है और परिणाम को 'कॉल' में निर्दिष्ट करता है इंट कॉल = कॉल (और एफ, 'ए'); // फिर से, '&' की आवश्यकता नहीं है
// विरासत: ध्यान दें कि वर्तमान कोड आधारों को बनाए रखने के लिए, उपरोक्त परिभाषा शैली का अभी भी पहले उपयोग किया जा सकता है; // तो नई शैली का उपयोग करके मूल प्रकार को इसके संदर्भ में परिभाषित किया जा सकता है।
// यह 'पीएफएन' को परिभाषित करता है, एक प्रकार का पॉइंटर-टू-टाइप-एफएन। टाइपपीफ एफएन *पीएफएन;
// 'पीएफएन' का उपयोग 'एफएन *' जहां कहीं भी किया जा सकता है पीएफएन पीएफएन = एफ; int CallP (पीएफएन एफएन, चार सी); </वाक्यविन्यास हाइलाइट>
सी ++
ये उदाहरण उपरोक्त परिभाषाओं का उपयोग करते हैं। विशेष रूप से, ध्यान दें कि उपरोक्त परिभाषा के लिए Fn
पॉइंटर-टू-सदस्य-फ़ंक्शन परिभाषाओं में उपयोग किया जा सकता है:
<वाक्यविन्यास लैंग = सीपीपी>
// यह 'सी' को परिभाषित करता है, समान स्थिर और सदस्य कार्यों वाला वर्ग,
// और फिर 'सी' नामक उदाहरण बनाता है
कक्षा सी {
जनता:
स्टेटिक इंट स्टेटिक (चार सी);
इंट सदस्य (चार सी);
} सी; // सी
// यह 'पी' को परिभाषित करता है, 'सी' के लिए एक सूचक है और इसे 'सी' का पता निर्दिष्ट करता है सी * पी = & सी;
// यह 'fn' को पॉइंटर-टू-'स्टेटिक' असाइन करता है। // चूंकि कोई 'यह' नहीं है, 'Fn' सही प्रकार है; और 'fn' का उपयोग ऊपर के रूप में किया जा सकता है। एफएन = और सी :: स्टेटिक;
// यह 'एम' को परिभाषित करता है, पॉइंटर-टू-मेंबर-ऑफ-'सी' टाइप 'एफएन' के साथ, // और इसे 'सी :: सदस्य' का पता निर्दिष्ट करता है। // आप इसे सभी पॉइंटर्स की तरह राइट-टू-लेफ्ट पढ़ सकते हैं: // 'एम' 'एफएन' प्रकार के वर्ग 'सी' के सदस्य के लिए सूचक है एफएन सी :: * एम = और सी :: सदस्य;
// यह 'सी' में 'सदस्य' को कॉल करने के लिए 'एम' का उपयोग करता है, परिणाम 'सीए' को निर्दिष्ट करता है int सीए = (सी। * एम) ('ए');
// यह 'पी' में 'सदस्य' को कॉल करने के लिए 'एम' का उपयोग करता है, परिणाम 'पीए' को निर्दिष्ट करता है int pA = (p->*m)('A');
// यह 'रेफरी' को परिभाषित करता है, ऐसा फ़ंक्शन जो संदर्भ-से-'सी' स्वीकार करता है, // पॉइंटर-टू-मेंबर-ऑफ-'C' टाइप 'Fn', और 'char', // फ़ंक्शन को कॉल करें और परिणाम लौटाएं इंट रेफ (सी एंड आर, एफएन सी :: * एम, चार सी) {
वापसी (आर। * एम) (सी);
} // संदर्भ (आर, एम, सी)
// यह 'Ptr' को परिभाषित करता है, ऐसा फंक्शन जो पॉइंटर-टू-'C' को स्वीकार करता है, // पॉइंटर-टू-मेंबर-ऑफ-'C' टाइप 'Fn', और 'char', // फ़ंक्शन को कॉल करें और परिणाम लौटाएं इंट पीआरटी (सी * पी, एफएन सी :: * एम, चार सी) {
वापसी (पी -> * एम) (सी);
} // पीआरटी (पी, एम, सी)
// विरासत: ध्यान दें कि वर्तमान कोड आधारों को बनाए रखने के लिए, उपरोक्त परिभाषा शैली का अभी भी पहले उपयोग किया जा सकता है; // तो नई शैली का उपयोग करके मूल प्रकार को इसके संदर्भ में परिभाषित किया जा सकता है।
// यह 'FnC' को परिभाषित करता है, एक प्रकार का पॉइंटर-टू-मेंबर-ऑफ-क्लास-'C' टाइप 'Fn' टाइपपीफ एफएन सी :: * एफएनसी;
// 'FnC' का उपयोग जहाँ कहीं भी 'Fn C::*' कर सकता है, किया जा सकता है एफएनसी एफएनसी = और सी :: सदस्य; इंट रेफपी (सी एंड पी, एफएनसी एम, चार सी); </वाक्यविन्यास हाइलाइट>
यह भी देखें
- प्रतिनिधिमंडल (कम्प्यूटिंग)
- फंक्शन ऑब्जेक्ट
- उच्च-क्रम समारोह
- प्रक्रियात्मक पैरामीटर
- क्लोजर (कंप्यूटर प्रोग्रामिंग)
- बेनामी कार्य
संदर्भ
- ↑ Andrew J. Miller. "Fortran Examples". Retrieved 2013-09-14.
- ↑ "The Function Pointer Tutorials". logo. Retrieved 2011-04-13.
Function Pointers are pointers, i.e. variables, which point to the address of a function
- ↑ "The Function Pointer Tutorials". logo. Retrieved 2011-04-13.
Important note: A function pointer always points to a function with a specific signature! Thus all functions, you want to use with the same function pointer, must have the same parameters and return-type!
- ↑ "Expertise: Intermediate Language: C++: Use Functor for Callbacks in C++". DevX.com. 2005-01-31. Retrieved 2011-04-13.
If you want to use a member function as a callback function, then the member function needs to be associated with an object of the class before it can be called. In this case, you can use functor [with an example on this page].
बाहरी संबंध
- FAQ on Function Pointers, things to avoid with function pointers, some information on using function objects
- Function Pointer Tutorials, a guide to C/C++ function pointers, callbacks, and function objects (functors)
- Member Function Pointers and the Fastest Possible C++ Delegates, CodeProject article by Don Clugston
- Pointer Tutorials Archived 2009-04-05 at the Wayback Machine, C++ documentation and tutorials
- C pointers explained Archived 2019-06-09 at the Wayback Machine a visual guide of pointers in C
- Secure Function Pointer and Callbacks in Windows Programming, CodeProject article by R. Selvam
- The C Book, Function Pointers in C by "The C Book"
- Function Pointers in dBASE dBL, Function Pointer in dBASE dBL