फंक्शन पॉइंटर: Difference between revisions

From Vigyanwiki
No edit summary
No edit summary
 
(9 intermediate revisions by 4 users not shown)
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}}
'''फ़ंक्शन पॉइंटर''', जिसे [[सबरूटीन]] पॉइंटर या प्रोसेस पॉइंटर भी कहा जाता है, [[सूचक (कंप्यूटर प्रोग्रामिंग)]] है जो किसी फ़ंक्शन को इंगित करता है। डेटा मान को संदर्भित करने के विरोध में, फ़ंक्शन पॉइंटर स्मृति के अंदर निष्पादन योग्य कोड को इंगित करता है। [[डेरेफरेंस ऑपरेटर]] फ़ंक्शन पॉइंटर संदर्भित सबरूटीन उत्पन्न करता है, जिसे सामान्य फ़ंक्शन कॉल की तरह ही प्रयुक्त किया जा सकता है और तर्क पारित किया जा सकता है। इस तरह के आह्वान को अप्रत्यक्ष कॉल के रूप में भी जाना जाता है, क्योंकि निश्चित पहचानकर्ता या पते के माध्यम से 'प्रत्यक्ष' के अतिरिक्त वेरिएबल के माध्यम से 'अप्रत्यक्ष रूप से' फ़ंक्शन का आह्वान किया जा रहा है।
एक फ़ंक्शन पॉइंटर, जिसे [[सबरूटीन]] पॉइंटर या प्रोसेस पॉइंटर भी कहा जाता है, एक [[सूचक (कंप्यूटर प्रोग्रामिंग)]] है जो किसी फ़ंक्शन को इंगित करता है। डेटा मान को संदर्भित करने के विरोध में, फ़ंक्शन पॉइंटर स्मृति के अंदर निष्पादन योग्य कोड को इंगित करता है। [[डेरेफरेंस ऑपरेटर]] फ़ंक्शन पॉइंटर संदर्भित सबरूटीन उत्पन्न करता है, जिसे सामान्य फ़ंक्शन कॉल की तरह ही प्रयुक्त किया जा सकता है और तर्क पारित किया जा सकता है। इस तरह के आह्वान को एक अप्रत्यक्ष कॉल के रूप में भी जाना जाता है, क्योंकि एक निश्चित पहचानकर्ता या पते के माध्यम से 'सीधे' के अतिरिक्त एक चर के माध्यम से 'अप्रत्यक्ष रूप से' फ़ंक्शन का आह्वान किया जा रहा है।


फ़ंक्शन पॉइंटर्स का उपयोग रन-टाइम मानों के आधार पर निष्पादित करने के लिए फ़ंक्शन का चयन करने का एक आसान विधि प्रदान करके कोड को सरल बनाने के लिए किया जा सकता है।
फ़ंक्शन पॉइंटर्स का उपयोग कार्यसमय मानों के आधार पर निष्पादित करने के लिए फ़ंक्शन का चयन करने का सरल विधि प्रदान करके कोड को सरल बनाने के लिए किया जा सकता है।


फंक्शन पॉइंटर्स [[तीसरी पीढ़ी की [[प्रोग्रामिंग भाषा]]]] द्वारा समर्थित हैं | तीसरी पीढ़ी की प्रोग्रामिंग भाषाएँ (जैसे 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>
फंक्शन पॉइंटर्स तीसरी पीढ़ी की [[प्रोग्रामिंग भाषा|प्रोग्रामिंग लैंग्वेज]] द्वारा समर्थित हैं | तीसरी पीढ़ी की प्रोग्रामिंग लैंग्वेज (जैसे पीएल/आई,कोबोल, [[फोरट्रान]],<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> डीबेस डीबीएल, और सी (प्रोग्रामिंग लैंग्वेज)) और [[ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग]] लैंग्वेज (जैसे सी ++, सी Sharp (प्रोग्रामिंग लैंग्वेज) | सी #, और डी(प्रोग्रामिंग लैंग्वेज)) आदि है।<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, साथ ही अधिक आधुनिक भाषाएँ जैसे [[पास्कल (प्रोग्रामिंग भाषा)]] और C (प्रोग्रामिंग भाषा) सामान्यतः इस तरह से फ़ंक्शन पॉइंटर्स को प्रयुक्त करती हैं।<ref>{{cite web
एक फ़ंक्शन (या सबरूटीन) सूचक का सरलतम कार्यान्वयन [[चर (कंप्यूटर विज्ञान)|वेरिएबल (कंप्यूटर विज्ञान)]] के रूप में होता है जिसमें निष्पादन योग्य मेमोरी के अंदर फ़ंक्शन का मेमोरी पता होता है। पुरानी तीसरी पीढ़ी की प्रोग्रामिंग लैंग्वेज | तीसरी पीढ़ी की लैंग्वेज जैसे पीएल/आई औरकोबोल, साथ ही अधिक आधुनिक लैंग्वेज जैसे [[पास्कल (प्रोग्रामिंग भाषा)|पास्कल (प्रोग्रामिंग लैंग्वेज)]] और सी (प्रोग्रामिंग लैंग्वेज) सामान्यतः इस तरह से फ़ंक्शन पॉइंटर्स को प्रयुक्त करती हैं।<ref>{{cite web
| access-date = 2011-04-13
| access-date = 2011-04-13
| publisher = logo
| publisher = logo
Line 16: Line 15:
| url = http://www.newty.de/fpt/intro.html#top}}</ref>
| url = http://www.newty.de/fpt/intro.html#top}}</ref>


 
=== सी में उदाहरण ===
=== सी === में उदाहरण
{{See also|#वैकल्पिक सी और सी ++ सिंटैक्स}}
{{See also|#Alternate C and C++ syntax}}
निम्नलिखित सी प्रोग्राम दो फ़ंक्शन पॉइंटर्स के उपयोग को दिखाता है:
निम्नलिखित सी प्रोग्राम दो फ़ंक्शन पॉइंटर्स के उपयोग को दिखाता है:
* func1 एक डबल-सटीक (डबल) पैरामीटर लेता है और दूसरा डबल देता है, और एक फ़ंक्शन को असाइन किया जाता है जो सेंटीमीटर को इंच में परिवर्तित करता है।
* func1 एक डबल-स्पष्ट (डबल) पैरामीटर लेता है और दूसरा डबल देता है, और फ़ंक्शन को समुनदेशित किया जाता है जो सेंटीमीटर को इंच में परिवर्तित करता है।
* func2 एक निरंतर वर्ण सरणी के साथ-साथ एक पूर्णांक के लिए एक सूचक लेता है और एक वर्ण को एक सूचक देता है, और एक C स्ट्रिंग हैंडलिंग फ़ंक्शन को सौंपा जाता है जो किसी वर्ण सरणी में दिए गए वर्ण की पहली घटना के लिए एक सूचक देता है।
* func2 निरंतर वर्ण सरणी के साथ-साथ पूर्णांक के लिए सूचक लेता है और वर्ण को सूचक देता है, और एक सी स्ट्रिंग हैंडलिंग फ़ंक्शन को सौंपा जाता है जो किसी वर्ण सरणी में दिए गए वर्ण की पहली घटना के लिए सूचक देता है।
<syntaxhighlight>
#include <stdio.h>  /* for printf */
#include <string.h> /* for strchr */


<वाक्यविन्यास प्रकाश लैंग = सी>
double cm_to_inches(double cm) {
#include <stdio.h> /* प्रिंटफ के लिए */
return cm / 2.54;
#include <string.h> /* strchr के लिए */
 
डबल सेमी_टू_इंच (डबल सेमी) {
वापसी सेमी / 2.54;
}
}


// strchr [[सी स्ट्रिंग हैंडलिंग]] का हिस्सा है (अर्थात, घोषणा की कोई आवश्यकता नहीं है)
// "strchr" is part of the C string handling (i.e., no need for declaration)
// https://en.wikipedia.org/wiki/C_string_handling#Functions देखें
// See https://en.wikipedia.org/wiki/C_string_handling#Functions


पूर्णांक मुख्य (शून्य) {
int main(void) {
डबल (*func1)(डबल) = cm_to_inches;
double (*func1)(double) = cm_to_inches;
चार * (* func2) (स्थिरांक चार *, int) = strchr;
char * (*func2)(const char *, int) = strchr;
प्रिंटफ (% f% s, func1 (15.0), func2 (विकिपीडिया, 'पी'));
printf("%f %s", func1(15.0), func2("Wikipedia", 'p'));
/* 5.905512 पीडिया प्रिंट करता है */
/* prints "5.905512 pedia" */
वापसी 0;
return 0;
}
}
</वाक्यविन्यास हाइलाइट>
</syntaxhighlight>


अगला प्रोग्राम दो कार्यों में से एक को प्रयुक्त करने के लिए फ़ंक्शन पॉइंटर का उपयोग करता है (<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>
अगला प्रोग्राम दो कार्यों में से एक को प्रयुक्त करने के लिए फ़ंक्शन पॉइंटर का उपयोग करता है (<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> मानक आउटपुट द्वारा लिखा जाता है .<syntaxhighlight>
#सम्मिलित  <गणित.एच>
#include <math.h>
#सम्मिलित  <stdio.h>
#include <stdio.h>


// फंक्शन एक तर्क के रूप में एक फ़ंक्शन पॉइंटर लेता है
// Function taking a function pointer as an argument
डबल कंप्यूट_सम (डबल (* funcp) (डबल), डबल लो, डबल हाय) {
double compute_sum(double (*funcp)(double), double lo, double hi) {
     दोहरा योग = 0.0;
     double sum = 0.0;


     // पॉइंट-टू-फ़ंक्शन '*funcp' द्वारा लौटाए गए मान जोड़ें
     // Add values returned by the pointed-to function '*funcp'
     int मैं;
     int i;
     के लिए (i = 0; i <= 100; i++) {
     for (i = 0; i <= 100; i++) {
         // फ़ंक्शन का आह्वान करने के लिए फ़ंक्शन पॉइंटर 'funcp' का उपयोग करें
         // Use the function pointer 'funcp' to invoke the function
         डबल एक्स = आई / 100.0 * (हाय - लो) + लो;
         double x = i / 100.0 * (hi - lo) + lo;
         डबल वाई = funcp (एक्स);
         double y = funcp(x);
         योग + = वाई;
         sum += y;
     }
     }
     वापसी राशि / 101.0 * (हाय - लो);
     return sum / 101.0 * (hi - lo);
}
}


डबल स्क्वायर (डबल एक्स) {
double square(double x) {
     वापसी एक्स * एक्स;
     return x * x;
}
}


पूर्णांक मुख्य (शून्य) {
int main(void) {
     दोहरी राशि;
     double  sum;


     // पॉइंट-टू-फ़ंक्शन के रूप में मानक लाइब्रेरी फ़ंक्शन 'sin ()' का उपयोग करें
     // Use standard library function 'sin()' as the pointed-to function
     योग = कंप्यूट_सम (पाप, 0.0, 1.0);
     sum = compute_sum(sin, 0.0, 1.0);
     प्रिंटफ (योग (पाप):% जी \ n, योग);
     printf("sum(sin): %g\n", sum);


     // पॉइंट-टू-फ़ंक्शन के रूप में मानक लाइब्रेरी फ़ंक्शन 'cos ()' का उपयोग करें
     // Use standard library function 'cos()' as the pointed-to function
     योग = कंप्यूट_सम (कॉस, 0.0, 1.0);
     sum = compute_sum(cos, 0.0, 1.0);
     प्रिंटफ (योग (cos):% g \ n, योग);
     printf("sum(cos): %g\n", sum);


     // यूजर-डिफ़ाइंड फ़ंक्शन 'स्क्वायर ()' को पॉइंट-टू-फ़ंक्शन के रूप में उपयोग करें
     // Use user-defined function 'square()' as the pointed-to function
     योग = कंप्यूट_सम (वर्ग, 0.0, 1.0);
     sum = compute_sum(square, 0.0, 1.0);
     प्रिंटफ (योग (वर्ग):% जी \ n, योग);
     printf("sum(square): %g\n", sum);


     वापसी 0;
     return 0;
}
}
</वाक्यविन्यास हाइलाइट>
</syntaxhighlight>


== फंक्टर्स ==
== फंक्टर्स ==
{{main|Function object}}
{{main|फंक्शन ऑब्जेक्ट}}
फ़ंक्टर, या फ़ंक्शन ऑब्जेक्ट, फ़ंक्शन पॉइंटर्स के समान हैं, और समान तरीकों से उपयोग किए जा सकते हैं। एक फ़ंक्टर एक वर्ग प्रकार का एक ऑब्जेक्ट है जो [[फ़ंक्शन-कॉल ऑपरेटर]] को प्रयुक्त करता है, ऑब्जेक्ट को फ़ंक्शन कॉल के समान सिंटैक्स का उपयोग करके एक्सप्रेशन के अंदर उपयोग करने की अनुमति देता है। फ़ंक्टर साधारण फ़ंक्शन पॉइंटर्स की तुलना में अधिक शक्तिशाली होते हैं, अपने स्वयं के डेटा मान रखने में सक्षम होते हैं, और प्रोग्रामर को [[क्लोजर (कंप्यूटर प्रोग्रामिंग)]] का अनुकरण करने की अनुमति देते हैं। कॉलबैक फ़ंक्शन के रूप में सदस्य फ़ंक्शन का उपयोग करना आवश्यक होने पर उन्हें कॉलबैक फ़ंक्शन के रूप में भी उपयोग किया जाता है।<ref>{{cite web
फ़ंक्टर, या फ़ंक्शन ऑब्जेक्ट, फ़ंक्शन पॉइंटर्स के समान हैं, और समान विधियों से उपयोग किए जा सकते हैं। फ़ंक्टर वर्ग प्रकार का ऑब्जेक्ट है जो [[फ़ंक्शन-कॉल ऑपरेटर]] को प्रयुक्त करता है, ऑब्जेक्ट को फ़ंक्शन कॉल के समान सिंटैक्स का उपयोग करके एक्सप्रेशन के अंदर उपयोग करने की अनुमति देता है। फ़ंक्टर साधारण फ़ंक्शन पॉइंटर्स की तुलना में अधिक शक्तिशाली होते हैं, अपने स्वयं के डेटा मान रखने में सक्षम होते हैं, और प्रोग्रामर को [[क्लोजर (कंप्यूटर प्रोग्रामिंग)]] का अनुकरण करने की अनुमति देते हैं। कॉलबैक फ़ंक्शन के रूप में सदस्य फ़ंक्शन का उपयोग करना आवश्यक होने पर उन्हें कॉलबैक फ़ंक्शन के रूप में भी उपयोग किया जाता है।<ref>{{cite web
| access-date = 2011-04-13
| access-date = 2011-04-13
| date = 2005-01-31
| date = 2005-01-31
Line 95: Line 91:
| title = Expertise: Intermediate Language: C++: Use Functor for Callbacks in C++
| title = Expertise: Intermediate Language: C++: Use Functor for Callbacks in C++
| quote = 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].
| quote = 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].
| url = http://www.devx.com/tips/Tip/27126}}</ref>
| url = http://www.devx.com/tips/Tip/27126}}</ref>  
कई शुद्ध वस्तु-उन्मुख भाषाएँ फ़ंक्शन पॉइंटर्स का समर्थन नहीं करती हैं। इस तरह की भाषाओं में कुछ समान प्रयुक्त किया जा सकता है, चूंकि, [[प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)]] के [[संदर्भ (कंप्यूटर विज्ञान)]] का उपयोग करके जो एकल [[विधि (कंप्यूटर प्रोग्रामिंग)]] (सदस्य फ़ंक्शन) को परिभाषित करता है। [[सीएलआई भाषाओं की सूची]] जैसे कि सी शार्प (प्रोग्रामिंग लैंग्वेज)|सी# और विज़ुअल बेसिक .NET इम्प्लीमेंट [[प्रकार की सुरक्षा]]|टाइप-सेफ फंक्शन पॉइंटर्स विद डेलिगेट (सीएलआई)।


अन्य भाषाओं में जो प्रथम श्रेणी के कार्यों का समर्थन करते हैं, कार्यों को डेटा के रूप में माना जाता है, और फ़ंक्शन पॉइंटर्स की आवश्यकता को समाप्त करते हुए, अन्य कार्यों द्वारा सीधे पारित किया जा सकता है, लौटाया जा सकता है और गतिशील रूप से बनाया जा सकता है।
कई शुद्ध वस्तु-उन्मुख लैंग्वेज फ़ंक्शन पॉइंटर्स का समर्थन नहीं करती हैं। इस तरह की भाषाओं में कुछ समान प्रयुक्त किया जा सकता है, चूंकि, [[प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)]] के [[संदर्भ (कंप्यूटर विज्ञान)]] का उपयोग करके जो एकल [[विधि (कंप्यूटर प्रोग्रामिंग)]] (सदस्य फ़ंक्शन) को परिभाषित करता है। [[सीएलआई भाषाओं की सूची]] जैसे कि सी शार्प (प्रोग्रामिंग लैंग्वेज)|सी# और विज़ुअल बेसिक .नेट इम्प्लीमेंट [[प्रकार की सुरक्षा]]|सुरक्षा प्रकार के फंक्शन पॉइंटर्स विद डेलिगेट (सीएलआई) है।


कार्यों को कॉल करने के लिए फ़ंक्शन पॉइंटर्स का व्यापक रूप से उपयोग आधुनिक प्रोसेसर पर कोड के लिए धीमा हो सकता है, क्योंकि एक [[शाखा भविष्यवक्ता]] यह पता लगाने में सक्षम नहीं हो सकता है कि कहां शाखा करना है (यह रन टाइम पर फ़ंक्शन पॉइंटर के मान पर निर्भर करता है) चूंकि इस प्रभाव को अतिरंजित किया जा सकता है क्योंकि अधिकांशतः गैर-अनुक्रमित तालिका लुकअप को अधिक कम करके इसकी भरपाई की जाती है।
अन्य भाषाओं में जो प्रथम श्रेणी के कार्यों का समर्थन करते हैं, कार्यों को डेटा के रूप में माना जाता है, और फ़ंक्शन पॉइंटर्स की आवश्यकता को समाप्त करते हुए, अन्य कार्यों द्वारा प्रत्यक्ष पारित किया जा सकता है, लौटाया जा सकता है और गतिशील रूप से बनाया जा सकता है।
 
कार्यों को कॉल करने के लिए फ़ंक्शन पॉइंटर्स का व्यापक रूप से उपयोग आधुनिक प्रोसेसर पर कोड के लिए धीमा हो सकता है, क्योंकि [[शाखा भविष्यवक्ता]] यह पता लगाने में सक्षम नहीं हो सकता है कि कहां शाखा करना है (यह कार्यसमय पर फ़ंक्शन पॉइंटर के मान पर निर्भर करता है) चूंकि इस प्रभाव को अतिरंजित किया जा सकता है क्योंकि अधिकांशतः गैर-अनुक्रमित तालिका लुकअप को अधिक कम करके इसकी आपूर्ति की जाती है।


== विधि संकेत ==
== विधि संकेत ==
C++ में ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग के लिए समर्थन सम्मिलित है, इसलिए कक्षाओं में विधि (कंप्यूटर प्रोग्रामिंग) हो सकती है (आमतौर पर सदस्य कार्यों के रूप में संदर्भित)। गैर-स्थैतिक सदस्य फ़ंक्शंस (इंस्टेंस मेथड्स) में एक निहित पैरामीटर ([[यह (कंप्यूटर प्रोग्रामिंग)]] पॉइंटर) होता है, जो उस ऑब्जेक्ट के लिए पॉइंटर होता है, जिस पर यह काम कर रहा है, इसलिए ऑब्जेक्ट के प्रकार को प्रकार के हिस्से के रूप में सम्मिलित किया जाना चाहिए। समारोह सूचक। विधि का उपयोग उस वर्ग के ऑब्जेक्ट पर पॉइंटर-टू-सदस्य ऑपरेटरों में से एक का उपयोग करके किया जाता है: <code>.*</code> या <code>->*</code> (किसी वस्तु या वस्तु के सूचक के लिए क्रमशः)।{{Dubious|date=December 2022}}
सी ++ में ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग के लिए समर्थन सम्मिलित है, इसलिए कक्षाओं में विधि (कंप्यूटर प्रोग्रामिंग) हो सकती है (सामान्यतः सदस्य कार्यों के रूप में संदर्भित)। गैर-स्थैतिक सदस्य फ़ंक्शंस (इंस्टेंस मेथड्स) में निहित पैरामीटर ([[यह (कंप्यूटर प्रोग्रामिंग)]] पॉइंटर) होता है, जो उस ऑब्जेक्ट के लिए पॉइंटर होता है, जिस पर यह काम कर रहा है, इसलिए ऑब्जेक्ट के प्रकार को प्रकार के हिस्से के रूप में सम्मिलित किया जाना चाहिए। फ़ंक्शन सूचक। विधि का उपयोग उस वर्ग के ऑब्जेक्ट पर पॉइंटर-टू-सदस्य ऑपरेटरों में से एक का उपयोग करके किया जाता है: <code>.*</code> या <code>->*</code> (किसी वस्तु या वस्तु के सूचक के लिए क्रमशः)।
चूंकि सी और सी ++ में फ़ंक्शन पॉइंटर्स को साधारण पते के रूप में प्रयुक्त किया जा सकता है, जिससेसामान्यतः <code>sizeof(Fx)==sizeof(void *)</code>, सी ++ में सदस्य पॉइंटर्स को कभी-कभी वसा पॉइंटर्स के रूप में कार्यान्वित किया जाता है, आमतौर पर वर्चुअल विधियों और वर्चुअल विरासत से निपटने के लिए एक साधारण फ़ंक्शन पॉइंटर के आकार के दो या तीन गुना{{Citation needed|date=August 2011}}.


== सी ++ == में
चूंकि सी और सी ++ में फ़ंक्शन पॉइंटर्स को साधारण पते के रूप में प्रयुक्त किया जा सकता है, जिससे सामान्यतः <code>sizeof(Fx)==sizeof(void *)</code>, सी ++ में सदस्य पॉइंटर्स को कभी-कभी वसा पॉइंटर्स के रूप में कार्यान्वित किया जाता है, सामान्यतः वर्चुअल विधियों और वर्चुअल विरासत से निपटने के लिए साधारण फ़ंक्शन पॉइंटर के आकार के दो या तीन गुना होता है.
C++ में, C में उपयोग की जाने वाली विधि के अतिरिक्त, C++ मानक लाइब्रेरी क्लास टेम्पलेट का उपयोग करना भी संभव है {{mono|std::function}}, जिनमें से उदाहरण फ़ंक्शन ऑब्जेक्ट हैं:


<वाक्यविन्यास लैंग = सीपीपी>
==== सी ++ में ====
#सम्मिलित  <iostream>
सी ++ में, सी में उपयोग की जाने वाली विधि के अतिरिक्त, सी ++ मानक लाइब्रेरी क्लास टेम्पलेट का उपयोग करना भी संभव है {{mono|std::function}}, जिनमें से उदाहरण फ़ंक्शन ऑब्जेक्ट हैं:<syntaxhighlight>
#सम्मिलित  <कार्यात्मक>
#include <iostream>
#include <functional>


स्टेटिक डबल डेरिवेटिव (स्थिरांक एसटीडी :: फ़ंक्शन <डबल (डबल)> और एफ, डबल एक्स 0, डबल ईपीएस) {
static double derivative(const std::function<double(double)> &f, double x0, double eps) {
     डबल ईपीएस2 = ईपीएस / 2;
     double eps2 = eps / 2;
     डबल लो = x0 - ईपीएस 2;
     double lo = x0 - eps2;
     डबल हाई = x0 + ईपीएस2;
     double hi = x0 + eps2;
     रिटर्न (एफ(हाय) - एफ(लो)) / ईपीएस;
     return (f(hi) - f(lo)) / eps;
}
}


स्टेटिक डबल एफ (डबल एक्स) {
static double f(double x) {
     वापसी एक्स * एक्स;
     return x * x;
}
}


मुख्य प्रवेश बिंदु() {
int main() {
     डबल एक्स = 1;
     double x = 1;
     std::cout << d/dx(x ^ 2) [@ x = << x << ] = << व्युत्पन्न (f, x, 1e-5) << std::endl;
     std::cout << "d/dx(x ^ 2) [@ x = " << x << "] = " << derivative(f, x, 1e-5) << std::endl;
     वापसी 0;
     return 0;
}
}
</वाक्यविन्यास हाइलाइट>
</syntaxhighlight>


=== सी ++ === में सदस्य कार्यों के लिए
==== सी ++ में सदस्य कार्यों के लिए ====
{{See also|#Alternate C and C++ Syntax}}
{{See also|#वैकल्पिक सी और सी ++ सिंटेक्स}}
कक्षाओं या स्ट्रक्चर्स के सदस्य कार्यों से निपटने के समयसी ++ फ़ंक्शन पॉइंटर्स का उपयोग करता है। इन्हें ऑब्जेक्ट पॉइंटर या इस कॉल का उपयोग करके बुलाया जाता है। वे इस प्रकार सुरक्षित हैं कि आप उस प्रकार के सूचक का उपयोग करके केवल उस वर्ग (या डेरिवेटिव) के सदस्यों को कॉल कर सकते हैं। यह उदाहरण सादगी के लिए जोड़े गए सदस्य फ़ंक्शन के सूचक के लिए टाइपपीफ के उपयोग को भी प्रदर्शित करता है। स्थैतिक सदस्य कार्यों के लिए फ़ंक्शन पॉइंटर्स पारंपरिक 'सी' शैली में किए जाते हैं क्योंकि इस कॉल के लिए कोई ऑब्जेक्ट पॉइंटर आवश्यक नहीं है।


<वाक्यविन्यास लैंग = सीपीपी>
कक्षाओं या स्ट्रक्वेरिएबल्स के सदस्य कार्यों से निपटने के समय सी ++ फ़ंक्शन पॉइंटर्स का उपयोग करता है। इन्हें ऑब्जेक्ट पॉइंटर या इस कॉल का उपयोग करके बुलाया जाता है। वे इस प्रकार सुरक्षित हैं कि आप उस प्रकार के सूचक का उपयोग करके केवल उस वर्ग (या डेरिवेटिव) के सदस्यों को कॉल कर सकते हैं। यह उदाहरण सादगी के लिए जोड़े गए सदस्य फ़ंक्शन के सूचक के लिए टाइपपीफ के उपयोग को भी प्रदर्शित करता है। स्थैतिक सदस्य कार्यों के लिए फ़ंक्शन पॉइंटर्स पारंपरिक 'सी' शैली में किए जाते हैं क्योंकि इस कॉल के लिए कोई ऑब्जेक्ट पॉइंटर आवश्यक नहीं है।<syntaxhighlight>
#सम्मिलित  <iostream>
#include <iostream>
नेमस्पेस एसटीडी का उपयोग करना;
using namespace std;


कक्षा फू {
class Foo {


जनता:
public:
     इंट ऐड (इंट आई, इंट जे) {
     int add(int i, int j) {
         वापसी मैं + जे;
         return i+j;
     }
     }
     इंट मल्टी (इंट आई, इंट जे) {
     int mult(int i, int j) {
         वापसी आई * जे;
         return i*j;
     }
     }
     स्टेटिक इंट नेगेट (इंट आई) {
     static int negate(int i) {
         वापसी -मैं;
         return -i;
     }
     }
};
};


int bar1 (int i, int j, Foo* pFoo, int(Foo::*pfn)(int,int)) {
int bar1(int i, int j, Foo* pFoo, int(Foo::*pfn)(int,int)) {
     वापसी (पीएफयू -> * पीएफएन) (आई, जे);
     return (pFoo->*pfn)(i,j);
}
}


टाइपपीफ इंट (फू :: * फू_पीएफएन) (इंट, इंट);
typedef int(Foo::*Foo_pfn)(int,int);


int bar2(int i, int j, Foo* pFoo, Foo_pfn pfn) {
int bar2(int i, int j, Foo* pFoo, Foo_pfn pfn) {
     वापसी (पीएफयू -> * पीएफएन) (आई, जे);
     return (pFoo->*pfn)(i,j);
}
}


टाइपपीफ इंट (* पीएफएन) (इंट);
typedef int(*PFN)(int);


इंट बार3(इंट आई, पीएफएन पीएफएन) {
int bar3(int i, PFN pfn) {
     रिटर्न पीएफएन (आई);
     return pfn(i);
}
}


मुख्य प्रवेश बिंदु() {
int main() {
     फू फू;
     Foo foo;
     cout << Foo::add(2,4) = << bar1(2,4, &foo, &Foo::add) << endl;
     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::mult(3,5) = " << bar2(3,5, &foo, &Foo::mult) << endl;
     cout << Foo::negate(6) = << bar3(6, &Foo::negate) << endl;
     cout << "Foo::negate(6) = " << bar3(6, &Foo::negate) << endl;
     वापसी 0;
     return 0;
}
}
</वाक्यविन्यास हाइलाइट>
</syntaxhighlight>


== वैकल्पिक सी और सी ++ सिंटैक्स ==
== वैकल्पिक सी और सी ++ सिंटैक्स ==
ऊपर दिया गया C और C++ सिंटैक्स सभी पाठ्य पुस्तकों में उपयोग किया जाने वाला विहित सिंटैक्स है - किन्तुइसे पढ़ना और समझाना जटिल है। ऊपर वाला भी <code>typedef</code> उदाहरण इस सिंटैक्स का उपयोग करते हैं। चूंकि, प्रत्येक सी और सी ++ कंपाइलर फ़ंक्शन पॉइंटर्स घोषित करने के लिए एक और स्पष्ट और संक्षिप्त तंत्र का समर्थन करता है: उपयोग करें <code>typedef</code>, किन्तुसूचक को परिभाषा के हिस्से के रूप में संग्रहीत न करें। ध्यान दें कि इस तरह का एकमात्र विधि <code>typedef</code> वास्तव में एक पॉइंटर के साथ उपयोग किया जा सकता है - किन्तुयह इसके पॉइंटर-नेस को हाइलाइट करता है।
ऊपर दिया गया सी और सी ++ सिंटैक्स सभी पाठ्य पुस्तकों में उपयोग किया जाने वाला विहित सिंटैक्स है - किन्तुइसे पढ़ना और समझाना जटिल है। ऊपर वाला भी <code>typedef</code> उदाहरण इस सिंटैक्स का उपयोग करते हैं। चूंकि, प्रत्येक सी और सी ++ कंपाइलर फ़ंक्शन पॉइंटर्स घोषित करने के लिए और स्पष्ट और संक्षिप्त तंत्र का समर्थन करता है: उपयोग करें <code>typedef</code>, किन्तुसूचक को परिभाषा के हिस्से के रूप में संग्रहीत न करें। ध्यान दें कि इस तरह का एकमात्र विधि <code>typedef</code> वास्तव में पॉइंटर के साथ उपयोग किया जा सकता है - किन्तुयह इसके पॉइंटर-नेस को हाइलाइट करता है।


=== सी और सी ++ ===
=== सी और सी ++ ===
<वाक्यविन्यास लैंग = सी>
<syntaxhighlight>
// यह 'एफ' की घोषणा करता है, एक ऐसा कार्य जो 'चार' को स्वीकार करता है और 'इंट' लौटाता है। परिभाषा कहीं और है।
// This declares 'F', a function that accepts a 'char' and returns an 'int'. Definition is elsewhere.
इंट एफ (चार सी);
int F(char c);


// यह 'एफएन' को परिभाषित करता है, एक प्रकार का फ़ंक्शन जो 'चार' स्वीकार करता है और 'इंट' देता है।
// This defines 'Fn', a type of function that accepts a 'char' and returns an 'int'.
टाइपपीफ इंट एफएन (चार सी);
typedef int Fn(char c);


// यह 'एफएन' को परिभाषित करता है, टाइप पॉइंटर-टू-'एफएन' का एक चर, और इसे 'एफ' का पता निर्दिष्ट करता है।
// This defines 'fn', a variable of type pointer-to-'Fn', and assigns the address of 'F' to it.
एफएन *एफएन = और एफ; // नोट 'और' की आवश्यकता नहीं है - किन्तुयह हाइलाइट करता है कि क्या किया जा रहा है।
Fn *fn = &F;     // Note '&' not required - but it highlights what is being done.


// यह 'fn' का उपयोग करके 'F' को कॉल करता है, परिणाम को 'a' चर के लिए निर्दिष्ट करता है
// This calls 'F' using 'fn', assigning the result to the variable 'a'
इंट ए = एफएन ('');
int a = fn('A');


// यह 'कॉल' को परिभाषित करता है, एक ऐसा फ़ंक्शन जो पॉइंटर-टू-'एफएन' स्वीकार करता है, इसे कॉल करता है, और परिणाम देता है
// This defines 'Call', a function that accepts a pointer-to-'Fn', calls it, and returns the result
इंट कॉल (एफएन * एफएन, चार सी) {
int Call(Fn *fn, char c) {
   वापसी एफएन (सी);
   return fn(c);
} // कॉल (एफएन, सी)
} // Call(fn, c)


// यह 'कॉल' फ़ंक्शन को कॉल करता है, 'एफ' में गुजरता है और परिणाम को 'कॉल' में निर्दिष्ट करता है
// This calls function 'Call', passing in 'F' and assigning the result to 'call'
इंट कॉल = कॉल (और एफ, ''); // फिर से, '&' की आवश्यकता नहीं है
int call = Call(&F, 'A');   // Again, '&' is not required


// विरासत: ध्यान दें कि वर्तमान  कोड आधारों को बनाए रखने के लिए, उपरोक्त परिभाषा शैली का अभी भी पहले उपयोग किया जा सकता है;
// LEGACY: Note that to maintain existing code bases, the above definition style can still be used first;
// तो नई शैली का उपयोग करके मूल प्रकार को इसके संदर्भ में परिभाषित किया जा सकता है।
// then the original type can be defined in terms of it using the new style.


// यह 'पीएफएन' को परिभाषित करता है, एक प्रकार का पॉइंटर-टू-टाइप-एफएन।
// This defines 'PFn', a type of pointer-to-type-Fn.
टाइपपीफ एफएन *पीएफएन;
typedef Fn *PFn;


// 'पीएफएन' का उपयोग 'एफएन *' जहां कहीं भी किया जा सकता है
// 'PFn' can be used wherever 'Fn *' can
पीएफएन पीएफएन = एफ;
PFn pfn = F;
int CallP (पीएफएन एफएन, चार सी);
int CallP(PFn fn, char c);
</वाक्यविन्यास हाइलाइट>
</syntaxhighlight>


=== सी ++ ===
=== सी ++ ===
ये उदाहरण उपरोक्त परिभाषाओं का उपयोग करते हैं। विशेष रूप से, ध्यान दें कि उपरोक्त परिभाषा के लिए <code>Fn</code> पॉइंटर-टू-सदस्य-फ़ंक्शन परिभाषाओं में उपयोग किया जा सकता है:
ये उदाहरण उपरोक्त परिभाषाओं का उपयोग करते हैं। विशेष रूप से, ध्यान दें कि उपरोक्त परिभाषा के लिए <code>Fn</code> पॉइंटर-टू-सदस्य-फ़ंक्शन परिभाषाओं में उपयोग किया जा सकता है:<syntaxhighlight>
<वाक्यविन्यास लैंग = सीपीपी>
// This defines 'C', a class with similar static and member functions,
// यह 'सी' को परिभाषित करता है, समान स्थिर और सदस्य कार्यों वाला एक वर्ग,
// and then creates an instance called 'c'
// और फिर 'सी' नामक एक उदाहरण बनाता है
class C {
कक्षा सी {
public:
जनता:
static int Static(char c);
स्टेटिक इंट स्टेटिक (चार सी);
int Member(char c);
इंट सदस्य (चार सी);
} c; // C
} सी; // सी


// यह 'पी' को परिभाषित करता है, 'सी' के लिए एक सूचक है और इसे 'सी' का पता निर्दिष्ट करता है
// This defines 'p', a pointer to 'C' and assigns the address of 'c' to it
सी * पी = & सी;
C *p = &c;


// यह 'fn' को पॉइंटर-टू-'स्टेटिक' असाइन करता है।
// This assigns a pointer-to-'Static' to 'fn'.
// चूंकि कोई 'यह' नहीं है, 'Fn' सही प्रकार है; और 'fn' का उपयोग ऊपर के रूप में किया जा सकता है।
// Since there is no 'this', 'Fn' is the correct type; and 'fn' can be used as above.
एफएन = और सी :: स्टेटिक;
fn = &C::Static;


// यह 'एम' को परिभाषित करता है, एक पॉइंटर-टू-मेंबर-ऑफ-'सी' टाइप 'एफएन' के साथ,
// This defines 'm', a pointer-to-member-of-'C' with type 'Fn',
// और इसे 'सी :: सदस्य' का पता निर्दिष्ट करता है।
// and assigns the address of 'C::Member' to it.
// आप इसे सभी पॉइंटर्स की तरह राइट-टू-लेफ्ट पढ़ सकते हैं:
// You can read it right-to-left like all pointers:
// 'एम' 'एफएन' प्रकार के वर्ग 'सी' के सदस्य के लिए सूचक है
// "'m' is a pointer to member of class 'C' of type 'Fn'"
एफएन सी :: * एम = और सी :: सदस्य;
Fn C::*m = &C::Member;


// यह 'सी' में 'सदस्य' को कॉल करने के लिए 'एम' का उपयोग करता है, परिणाम 'सीए' को निर्दिष्ट करता है
// This uses 'm' to call 'Member' in 'c', assigning the result to 'cA'
int सीए = (सी। * एम) ('');
int cA = (c.*m)('A');


// यह 'पी' में 'सदस्य' को कॉल करने के लिए 'एम' का उपयोग करता है, परिणाम 'पीए' को निर्दिष्ट करता है
// This uses 'm' to call 'Member' in 'p', assigning the result to 'pA'
int pA = (p->*m)('A');
int pA = (p->*m)('A');


// यह 'रेफरी' को परिभाषित करता है, एक ऐसा फ़ंक्शन जो संदर्भ-से-'सी' स्वीकार करता है,
// This defines 'Ref', a function that accepts a reference-to-'C',
// एक पॉइंटर-टू-मेंबर-ऑफ-'C' टाइप 'Fn', और एक 'char',
// a pointer-to-member-of-'C' of type 'Fn', and a 'char',
// फ़ंक्शन को कॉल करें और परिणाम लौटाएं
// calls the function and returns the result
इंट रेफ (सी एंड आर, एफएन सी :: * एम, चार सी) {
int Ref(C &r, Fn C::*m, char c) {
   वापसी (आर। * एम) (सी);
   return (r.*m)(c);
} // संदर्भ (आर, एम, सी)
} // Ref(r, m, c)


// यह 'Ptr' को परिभाषित करता है, एक ऐसा फंक्शन जो पॉइंटर-टू-'C' को स्वीकार करता है,
// This defines 'Ptr', a function that accepts a pointer-to-'C',
// एक पॉइंटर-टू-मेंबर-ऑफ-'C' टाइप 'Fn', और एक 'char',
// a pointer-to-member-of-'C' of type 'Fn', and a 'char',
// फ़ंक्शन को कॉल करें और परिणाम लौटाएं
// calls the function and returns the result
इंट पीआरटी (सी * पी, एफएन सी :: * एम, चार सी) {
int Ptr(C *p, Fn C::*m, char c) {
   वापसी (पी -> * एम) (सी);
   return (p->*m)(c);
} // पीआरटी (पी, एम, सी)
} // Ptr(p, m, c)


// विरासत: ध्यान दें कि वर्तमान  कोड आधारों को बनाए रखने के लिए, उपरोक्त परिभाषा शैली का अभी भी पहले उपयोग किया जा सकता है;
// LEGACY: Note that to maintain existing code bases, the above definition style can still be used first;
// तो नई शैली का उपयोग करके मूल प्रकार को इसके संदर्भ में परिभाषित किया जा सकता है।
// then the original type can be defined in terms of it using the new style.


// यह 'FnC' को परिभाषित करता है, एक प्रकार का पॉइंटर-टू-मेंबर-ऑफ-क्लास-'C' टाइप 'Fn'
// This defines 'FnC', a type of pointer-to-member-of-class-'C' of type 'Fn'
टाइपपीफ एफएन सी :: * एफएनसी;
typedef Fn C::*FnC;


// 'FnC' का उपयोग जहाँ कहीं भी 'Fn C::*' कर सकता है, किया जा सकता है
// 'FnC' can be used wherever 'Fn C::*' can
एफएनसी एफएनसी = और सी :: सदस्य;
FnC fnC = &C::Member;
इंट रेफपी (सी एंड पी, एफएनसी एम, चार सी);
int RefP(C &p, FnC m, char c);
</वाक्यविन्यास हाइलाइट>
</syntaxhighlight>


== यह भी देखें ==
== यह भी देखें ==
* [[प्रतिनिधिमंडल (कम्प्यूटिंग)]]
* [[प्रतिनिधिमंडल (कम्प्यूटिंग)]]
* [[फंक्शन ऑब्जेक्ट]]
* [[फंक्शन ऑब्जेक्ट]]
* [[उच्च-क्रम समारोह]]
* [[उच्च-क्रम समारोह|उच्च-क्रम फ़ंक्शन]]
* [[प्रक्रियात्मक पैरामीटर]]
* [[प्रक्रियात्मक पैरामीटर]]
* क्लोजर (कंप्यूटर प्रोग्रामिंग)
* क्लोजर (कंप्यूटर प्रोग्रामिंग)
* बेनामी कार्य
* नामरहित कार्य


==संदर्भ==
==संदर्भ==
Line 283: Line 277:
==बाहरी संबंध==
==बाहरी संबंध==
* [https://web.archive.org/web/20041013202445/http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.12 FAQ on Function Pointers], things to avoid with function pointers, some information on using [[function object]]s
* [https://web.archive.org/web/20041013202445/http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.12 FAQ on Function Pointers], things to avoid with function pointers, some information on using [[function object]]s
* [http://www.newty.de/fpt/ Function Pointer Tutorials], a guide to C/C++ function pointers, [[callback (computer programming)|callbacks]], and [[function object]]s (functors)
* [http://www.newty.de/fpt/ Function Pointer Tutorials], a guide to C/सी ++ function pointers, [[callback (computer programming)|callbacks]], and [[function object]]s (functors)
* [http://www.codeproject.com/KB/cpp/FastDelegate.aspx Member Function Pointers and the Fastest Possible C++ Delegates], CodeProject article by Don Clugston
* [http://www.codeproject.com/KB/cpp/FastDelegate.aspx Member Function Pointers and the Fastest Possible सी ++ Delegates], CodeProject article by Don Clugston
* [http://www.cplusplus.com/doc/tutorial/pointers.html Pointer Tutorials] {{Webarchive|url=https://web.archive.org/web/20090405234937/http://www.cplusplus.com/doc/tutorial/pointers.html |date=2009-04-05 }}, C++ documentation and tutorials
* [http://www.cplusplus.com/doc/tutorial/pointers.html Pointer Tutorials] {{Webarchive|url=https://web.archive.org/web/20090405234937/http://www.cplusplus.com/doc/tutorial/pointers.html |date=2009-04-05 }}, सी ++ documentation and tutorials
* [http://www.onlinecomputerteacher.net/pointers-in-c.html C pointers explained] {{Webarchive|url=https://web.archive.org/web/20190609120644/http://www.onlinecomputerteacher.net/pointers-in-c.html |date=2019-06-09 }} a visual guide of pointers in C
* [http://www.onlinecomputerteacher.net/pointers-in-c.html C pointers explained] {{Webarchive|url=https://web.archive.org/web/20190609120644/http://www.onlinecomputerteacher.net/pointers-in-c.html |date=2019-06-09 }} a visual guide of pointers in C
* [http://www.codeproject.com/KB/security/Securefunctionpointer.aspx Secure Function Pointer and Callbacks in Windows Programming], CodeProject article by R. Selvam
* [http://www.codeproject.com/KB/security/Securefunctionpointer.aspx Secure Function Pointer and Callbacks in Windows Programming], CodeProject article by R. Selvam
* [http://publications.gbdirect.co.uk/c_book/chapter5/function_pointers.html The C Book], Function Pointers in C by "The C Book"
* [http://publications.gbdirect.co.uk/c_book/chapter5/function_pointers.html The C Book], Function Pointers in C by "The C Book"
* [http://www.dbase.com/help/2_80/Language_Definition/IDH_LDEF_FUNCPOINTERS.htm Function Pointers in dBASE dBL], Function Pointer in dBASE dBL
* [http://www.dbase.com/help/2_80/Language_Definition/IDH_LDEF_FUNCPOINTERS.htm Function Pointers in डीबेस डीबीएल], Function Pointer in डीबेस डीबीएल
[[Category: डेटा के प्रकार]] [[Category: सबरूटीन्स]] [[Category: उदाहरण सी कोड वाले लेख]] [[Category: C++ कोड उदाहरण के साथ लेख]]
   


[[de:Zeiger (Informatik)#Funktionszeiger (Methodenzeiger)]]
[[de:Zeiger (Informatik)#Funktionszeiger (Methodenzeiger)]]


 
[[Category:Articles with hatnote templates targeting a nonexistent page]]
 
[[Category:C++ कोड उदाहरण के साथ लेख]]
[[Category: Machine Translated Page]]
[[Category:Created On 18/02/2023]]
[[Category:Created On 18/02/2023]]
[[Category:Lua-based templates]]
[[Category:Machine Translated Page]]
[[Category:Pages with script errors]]
[[Category:Pages with syntax highlighting errors]]
[[Category:Short description with empty Wikidata description]]
[[Category:Templates Vigyan Ready]]
[[Category:Templates that add a tracking category]]
[[Category:Templates that generate short descriptions]]
[[Category:Templates using TemplateData]]
[[Category:Webarchive template wayback links]]
[[Category:उदाहरण सी कोड वाले लेख]]
[[Category:डेटा के प्रकार]]
[[Category:सबरूटीन्स]]

Latest revision as of 15:34, 13 September 2023

फ़ंक्शन पॉइंटर, जिसे सबरूटीन पॉइंटर या प्रोसेस पॉइंटर भी कहा जाता है, सूचक (कंप्यूटर प्रोग्रामिंग) है जो किसी फ़ंक्शन को इंगित करता है। डेटा मान को संदर्भित करने के विरोध में, फ़ंक्शन पॉइंटर स्मृति के अंदर निष्पादन योग्य कोड को इंगित करता है। डेरेफरेंस ऑपरेटर फ़ंक्शन पॉइंटर संदर्भित सबरूटीन उत्पन्न करता है, जिसे सामान्य फ़ंक्शन कॉल की तरह ही प्रयुक्त किया जा सकता है और तर्क पारित किया जा सकता है। इस तरह के आह्वान को अप्रत्यक्ष कॉल के रूप में भी जाना जाता है, क्योंकि निश्चित पहचानकर्ता या पते के माध्यम से 'प्रत्यक्ष' के अतिरिक्त वेरिएबल के माध्यम से 'अप्रत्यक्ष रूप से' फ़ंक्शन का आह्वान किया जा रहा है।

फ़ंक्शन पॉइंटर्स का उपयोग कार्यसमय मानों के आधार पर निष्पादित करने के लिए फ़ंक्शन का चयन करने का सरल विधि प्रदान करके कोड को सरल बनाने के लिए किया जा सकता है।

फंक्शन पॉइंटर्स तीसरी पीढ़ी की प्रोग्रामिंग लैंग्वेज द्वारा समर्थित हैं | तीसरी पीढ़ी की प्रोग्रामिंग लैंग्वेज (जैसे पीएल/आई,कोबोल, फोरट्रान,[1] डीबेस डीबीएल, और सी (प्रोग्रामिंग लैंग्वेज)) और ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग लैंग्वेज (जैसे सी ++, सी Sharp (प्रोग्रामिंग लैंग्वेज) | सी #, और डी(प्रोग्रामिंग लैंग्वेज)) आदि है।[2]


सरल फ़ंक्शन पॉइंटर्स

एक फ़ंक्शन (या सबरूटीन) सूचक का सरलतम कार्यान्वयन वेरिएबल (कंप्यूटर विज्ञान) के रूप में होता है जिसमें निष्पादन योग्य मेमोरी के अंदर फ़ंक्शन का मेमोरी पता होता है। पुरानी तीसरी पीढ़ी की प्रोग्रामिंग लैंग्वेज | तीसरी पीढ़ी की लैंग्वेज जैसे पीएल/आई औरकोबोल, साथ ही अधिक आधुनिक लैंग्वेज जैसे पास्कल (प्रोग्रामिंग लैंग्वेज) और सी (प्रोग्रामिंग लैंग्वेज) सामान्यतः इस तरह से फ़ंक्शन पॉइंटर्स को प्रयुक्त करती हैं।[3]

सी में उदाहरण

निम्नलिखित सी प्रोग्राम दो फ़ंक्शन पॉइंटर्स के उपयोग को दिखाता है:

  • func1 एक डबल-स्पष्ट (डबल) पैरामीटर लेता है और दूसरा डबल देता है, और फ़ंक्शन को समुनदेशित किया जाता है जो सेंटीमीटर को इंच में परिवर्तित करता है।
  • func2 निरंतर वर्ण सरणी के साथ-साथ पूर्णांक के लिए सूचक लेता है और वर्ण को सूचक देता है, और एक सी स्ट्रिंग हैंडलिंग फ़ंक्शन को सौंपा जाता है जो किसी वर्ण सरणी में दिए गए वर्ण की पहली घटना के लिए सूचक देता है।
#include <stdio.h>  /* for printf */
#include <string.h> /* for strchr */

double cm_to_inches(double cm) {
	return cm / 2.54;
}

// "strchr" is part of the C string handling (i.e., no need for declaration)
// See https://en.wikipedia.org/wiki/C_string_handling#Functions

int main(void) {
	double (*func1)(double) = cm_to_inches;
	char * (*func2)(const char *, int) = strchr;
	printf("%f %s", func1(15.0), func2("Wikipedia", 'p'));
	/* prints "5.905512 pedia" */
	return 0;
}


अगला प्रोग्राम दो कार्यों में से एक को प्रयुक्त करने के लिए फ़ंक्शन पॉइंटर का उपयोग करता है (sin या cos) अप्रत्यक्ष रूप से किसी अन्य फ़ंक्शन से (compute_sum, फ़ंक्शन के रिमेंन एकीकरण के अनुमान की गणना)। कार्यक्रम कार्य करके संचालित होता है main कॉल फ़ंक्शन compute_sum दो बार, इसे लाइब्रेरी फ़ंक्शन के लिए पॉइंटर पास करना sin पहली बार, और कार्य करने के लिए सूचक cos सेकंड समय। फ़ंक्शन compute_sum बदले में अपने फ़ंक्शन पॉइंटर तर्क को संदर्भित करके अप्रत्यक्ष रूप से दो कार्यों में से एक को आमंत्रित करता है funcp कई बार, उन मानों को साथ जोड़कर जो इनवोक किए गए फ़ंक्शन लौटाते हैं और परिणामी राशि लौटाते हैं। दो राशियों को main मानक आउटपुट द्वारा लिखा जाता है .

#include <math.h>
#include <stdio.h>

// Function taking a function pointer as an argument
double compute_sum(double (*funcp)(double), double lo, double hi) {
    double sum = 0.0;

    // Add values returned by the pointed-to function '*funcp'
    int i;
    for (i = 0; i <= 100; i++) {
        // Use the function pointer 'funcp' to invoke the function
        double x = i / 100.0 * (hi - lo) + lo;
        double y = funcp(x);
        sum += y;
    }
    return sum / 101.0 * (hi - lo);
}

double square(double x) {
     return x * x;
}

int main(void) {
    double  sum;

    // Use standard library function 'sin()' as the pointed-to function
    sum = compute_sum(sin, 0.0, 1.0);
    printf("sum(sin): %g\n", sum);

    // Use standard library function 'cos()' as the pointed-to function
    sum = compute_sum(cos, 0.0, 1.0);
    printf("sum(cos): %g\n", sum);

    // Use user-defined function 'square()' as the pointed-to function
    sum = compute_sum(square, 0.0, 1.0);
    printf("sum(square): %g\n", sum);

    return 0;
}

फंक्टर्स

फ़ंक्टर, या फ़ंक्शन ऑब्जेक्ट, फ़ंक्शन पॉइंटर्स के समान हैं, और समान विधियों से उपयोग किए जा सकते हैं। फ़ंक्टर वर्ग प्रकार का ऑब्जेक्ट है जो फ़ंक्शन-कॉल ऑपरेटर को प्रयुक्त करता है, ऑब्जेक्ट को फ़ंक्शन कॉल के समान सिंटैक्स का उपयोग करके एक्सप्रेशन के अंदर उपयोग करने की अनुमति देता है। फ़ंक्टर साधारण फ़ंक्शन पॉइंटर्स की तुलना में अधिक शक्तिशाली होते हैं, अपने स्वयं के डेटा मान रखने में सक्षम होते हैं, और प्रोग्रामर को क्लोजर (कंप्यूटर प्रोग्रामिंग) का अनुकरण करने की अनुमति देते हैं। कॉलबैक फ़ंक्शन के रूप में सदस्य फ़ंक्शन का उपयोग करना आवश्यक होने पर उन्हें कॉलबैक फ़ंक्शन के रूप में भी उपयोग किया जाता है।[4]

कई शुद्ध वस्तु-उन्मुख लैंग्वेज फ़ंक्शन पॉइंटर्स का समर्थन नहीं करती हैं। इस तरह की भाषाओं में कुछ समान प्रयुक्त किया जा सकता है, चूंकि, प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) के संदर्भ (कंप्यूटर विज्ञान) का उपयोग करके जो एकल विधि (कंप्यूटर प्रोग्रामिंग) (सदस्य फ़ंक्शन) को परिभाषित करता है। सीएलआई भाषाओं की सूची जैसे कि सी शार्प (प्रोग्रामिंग लैंग्वेज)|सी# और विज़ुअल बेसिक .नेट इम्प्लीमेंट प्रकार की सुरक्षा|सुरक्षा प्रकार के फंक्शन पॉइंटर्स विद डेलिगेट (सीएलआई) है।

अन्य भाषाओं में जो प्रथम श्रेणी के कार्यों का समर्थन करते हैं, कार्यों को डेटा के रूप में माना जाता है, और फ़ंक्शन पॉइंटर्स की आवश्यकता को समाप्त करते हुए, अन्य कार्यों द्वारा प्रत्यक्ष पारित किया जा सकता है, लौटाया जा सकता है और गतिशील रूप से बनाया जा सकता है।

कार्यों को कॉल करने के लिए फ़ंक्शन पॉइंटर्स का व्यापक रूप से उपयोग आधुनिक प्रोसेसर पर कोड के लिए धीमा हो सकता है, क्योंकि शाखा भविष्यवक्ता यह पता लगाने में सक्षम नहीं हो सकता है कि कहां शाखा करना है (यह कार्यसमय पर फ़ंक्शन पॉइंटर के मान पर निर्भर करता है) चूंकि इस प्रभाव को अतिरंजित किया जा सकता है क्योंकि अधिकांशतः गैर-अनुक्रमित तालिका लुकअप को अधिक कम करके इसकी आपूर्ति की जाती है।

विधि संकेत

सी ++ में ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग के लिए समर्थन सम्मिलित है, इसलिए कक्षाओं में विधि (कंप्यूटर प्रोग्रामिंग) हो सकती है (सामान्यतः सदस्य कार्यों के रूप में संदर्भित)। गैर-स्थैतिक सदस्य फ़ंक्शंस (इंस्टेंस मेथड्स) में निहित पैरामीटर (यह (कंप्यूटर प्रोग्रामिंग) पॉइंटर) होता है, जो उस ऑब्जेक्ट के लिए पॉइंटर होता है, जिस पर यह काम कर रहा है, इसलिए ऑब्जेक्ट के प्रकार को प्रकार के हिस्से के रूप में सम्मिलित किया जाना चाहिए। फ़ंक्शन सूचक। विधि का उपयोग उस वर्ग के ऑब्जेक्ट पर पॉइंटर-टू-सदस्य ऑपरेटरों में से एक का उपयोग करके किया जाता है: .* या ->* (किसी वस्तु या वस्तु के सूचक के लिए क्रमशः)।

चूंकि सी और सी ++ में फ़ंक्शन पॉइंटर्स को साधारण पते के रूप में प्रयुक्त किया जा सकता है, जिससे सामान्यतः sizeof(Fx)==sizeof(void *), सी ++ में सदस्य पॉइंटर्स को कभी-कभी वसा पॉइंटर्स के रूप में कार्यान्वित किया जाता है, सामान्यतः वर्चुअल विधियों और वर्चुअल विरासत से निपटने के लिए साधारण फ़ंक्शन पॉइंटर के आकार के दो या तीन गुना होता है.

सी ++ में

सी ++ में, सी में उपयोग की जाने वाली विधि के अतिरिक्त, सी ++ मानक लाइब्रेरी क्लास टेम्पलेट का उपयोग करना भी संभव है std::function, जिनमें से उदाहरण फ़ंक्शन ऑब्जेक्ट हैं:

#include <iostream>
#include <functional>

static double derivative(const std::function<double(double)> &f, double x0, double eps) {
    double eps2 = eps / 2;
    double lo = x0 - eps2;
    double hi = x0 + eps2;
    return (f(hi) - f(lo)) / eps;
}

static double f(double x) {
    return x * x;
}

int main() {
    double x = 1;
    std::cout << "d/dx(x ^ 2) [@ x = " << x << "] = " << derivative(f, x, 1e-5) << std::endl;
    return 0;
}

सी ++ में सदस्य कार्यों के लिए

कक्षाओं या स्ट्रक्वेरिएबल्स के सदस्य कार्यों से निपटने के समय सी ++ फ़ंक्शन पॉइंटर्स का उपयोग करता है। इन्हें ऑब्जेक्ट पॉइंटर या इस कॉल का उपयोग करके बुलाया जाता है। वे इस प्रकार सुरक्षित हैं कि आप उस प्रकार के सूचक का उपयोग करके केवल उस वर्ग (या डेरिवेटिव) के सदस्यों को कॉल कर सकते हैं। यह उदाहरण सादगी के लिए जोड़े गए सदस्य फ़ंक्शन के सूचक के लिए टाइपपीफ के उपयोग को भी प्रदर्शित करता है। स्थैतिक सदस्य कार्यों के लिए फ़ंक्शन पॉइंटर्स पारंपरिक 'सी' शैली में किए जाते हैं क्योंकि इस कॉल के लिए कोई ऑब्जेक्ट पॉइंटर आवश्यक नहीं है।

#include <iostream>
using namespace std;

class Foo {

public:
    int add(int i, int j) {
        return i+j;
    }
    int mult(int i, int j) {
        return i*j;
    }
    static int negate(int i) {
        return -i;
    }
};

int bar1(int i, int j, Foo* pFoo, int(Foo::*pfn)(int,int)) {
    return (pFoo->*pfn)(i,j);
}

typedef int(Foo::*Foo_pfn)(int,int);

int bar2(int i, int j, Foo* pFoo, Foo_pfn pfn) {
    return (pFoo->*pfn)(i,j);
}

typedef int(*PFN)(int);

int bar3(int i, PFN pfn) {
    return pfn(i);
}

int main() {
    Foo foo;
    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;
    return 0;
}

वैकल्पिक सी और सी ++ सिंटैक्स

ऊपर दिया गया सी और सी ++ सिंटैक्स सभी पाठ्य पुस्तकों में उपयोग किया जाने वाला विहित सिंटैक्स है - किन्तुइसे पढ़ना और समझाना जटिल है। ऊपर वाला भी typedef उदाहरण इस सिंटैक्स का उपयोग करते हैं। चूंकि, प्रत्येक सी और सी ++ कंपाइलर फ़ंक्शन पॉइंटर्स घोषित करने के लिए और स्पष्ट और संक्षिप्त तंत्र का समर्थन करता है: उपयोग करें typedef, किन्तुसूचक को परिभाषा के हिस्से के रूप में संग्रहीत न करें। ध्यान दें कि इस तरह का एकमात्र विधि typedef वास्तव में पॉइंटर के साथ उपयोग किया जा सकता है - किन्तुयह इसके पॉइंटर-नेस को हाइलाइट करता है।

सी और सी ++

// This declares 'F', a function that accepts a 'char' and returns an 'int'. Definition is elsewhere.
int F(char c);

// This defines 'Fn', a type of function that accepts a 'char' and returns an 'int'.
typedef int Fn(char c);

// This defines 'fn', a variable of type pointer-to-'Fn', and assigns the address of 'F' to it.
Fn *fn = &F;      // Note '&' not required - but it highlights what is being done.

// This calls 'F' using 'fn', assigning the result to the variable 'a'
int a = fn('A');

// This defines 'Call', a function that accepts a pointer-to-'Fn', calls it, and returns the result
int Call(Fn *fn, char c) {
   return fn(c);
} // Call(fn, c)

// This calls function 'Call', passing in 'F' and assigning the result to 'call'
int call = Call(&F, 'A');   // Again, '&' is not required

// LEGACY: Note that to maintain existing code bases, the above definition style can still be used first;
// then the original type can be defined in terms of it using the new style.

// This defines 'PFn', a type of pointer-to-type-Fn.
typedef Fn *PFn;

// 'PFn' can be used wherever 'Fn *' can
PFn pfn = F;
int CallP(PFn fn, char c);

सी ++

ये उदाहरण उपरोक्त परिभाषाओं का उपयोग करते हैं। विशेष रूप से, ध्यान दें कि उपरोक्त परिभाषा के लिए Fn पॉइंटर-टू-सदस्य-फ़ंक्शन परिभाषाओं में उपयोग किया जा सकता है:

// This defines 'C', a class with similar static and member functions,
// and then creates an instance called 'c'
class C {
public:
static int Static(char c);
int Member(char c);
} c; // C

// This defines 'p', a pointer to 'C' and assigns the address of 'c' to it
C *p = &c;

// This assigns a pointer-to-'Static' to 'fn'.
// Since there is no 'this', 'Fn' is the correct type; and 'fn' can be used as above.
fn = &C::Static;

// This defines 'm', a pointer-to-member-of-'C' with type 'Fn',
// and assigns the address of 'C::Member' to it.
// You can read it right-to-left like all pointers:
// "'m' is a pointer to member of class 'C' of type 'Fn'"
Fn C::*m = &C::Member;

// This uses 'm' to call 'Member' in 'c', assigning the result to 'cA'
int cA = (c.*m)('A');

// This uses 'm' to call 'Member' in 'p', assigning the result to 'pA'
int pA = (p->*m)('A');

// This defines 'Ref', a function that accepts a reference-to-'C',
// a pointer-to-member-of-'C' of type 'Fn', and a 'char',
// calls the function and returns the result
int Ref(C &r, Fn C::*m, char c) {
   return (r.*m)(c);
} // Ref(r, m, c)

// This defines 'Ptr', a function that accepts a pointer-to-'C',
// a pointer-to-member-of-'C' of type 'Fn', and a 'char',
// calls the function and returns the result
int Ptr(C *p, Fn C::*m, char c) {
   return (p->*m)(c);
} // Ptr(p, m, c)

// LEGACY: Note that to maintain existing code bases, the above definition style can still be used first;
// then the original type can be defined in terms of it using the new style.

// This defines 'FnC', a type of pointer-to-member-of-class-'C' of type 'Fn'
typedef Fn C::*FnC;

// 'FnC' can be used wherever 'Fn C::*' can
FnC fnC = &C::Member;
int RefP(C &p, FnC m, char c);

यह भी देखें

संदर्भ

  1. Andrew J. Miller. "Fortran Examples". Retrieved 2013-09-14.
  2. "The Function Pointer Tutorials". logo. Retrieved 2011-04-13. Function Pointers are pointers, i.e. variables, which point to the address of a function
  3. "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!
  4. "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].


बाहरी संबंध