फंक्शन पॉइंटर: 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}} | ||
'''फ़ंक्शन पॉइंटर''', जिसे [[सबरूटीन]] पॉइंटर या प्रोसेस पॉइंटर भी कहा जाता है, [[सूचक (कंप्यूटर प्रोग्रामिंग)]] है जो किसी फ़ंक्शन को इंगित करता है। डेटा मान को संदर्भित करने के विरोध में, फ़ंक्शन पॉइंटर स्मृति के अंदर निष्पादन योग्य कोड को इंगित करता है। [[डेरेफरेंस ऑपरेटर]] फ़ंक्शन पॉइंटर संदर्भित सबरूटीन उत्पन्न करता है, जिसे सामान्य फ़ंक्शन कॉल की तरह ही प्रयुक्त किया जा सकता है और तर्क पारित किया जा सकता है। इस तरह के आह्वान को अप्रत्यक्ष कॉल के रूप में भी जाना जाता है, क्योंकि निश्चित पहचानकर्ता या पते के माध्यम से 'प्रत्यक्ष' के अतिरिक्त वेरिएबल के माध्यम से 'अप्रत्यक्ष रूप से' फ़ंक्शन का आह्वान किया जा रहा है। | |||
फ़ंक्शन पॉइंटर्स का उपयोग | फ़ंक्शन पॉइंटर्स का उपयोग कार्यसमय मानों के आधार पर निष्पादित करने के लिए फ़ंक्शन का चयन करने का सरल विधि प्रदान करके कोड को सरल बनाने के लिए किया जा सकता है। | ||
फंक्शन पॉइंटर्स | फंक्शन पॉइंटर्स तीसरी पीढ़ी की [[प्रोग्रामिंग भाषा|प्रोग्रामिंग लैंग्वेज]] द्वारा समर्थित हैं | तीसरी पीढ़ी की प्रोग्रामिंग लैंग्वेज (जैसे पीएल/आई,कोबोल, [[फोरट्रान]],<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> | ||
== सरल फ़ंक्शन पॉइंटर्स == | == सरल फ़ंक्शन पॉइंटर्स == | ||
एक फ़ंक्शन (या सबरूटीन) सूचक का सरलतम कार्यान्वयन | एक फ़ंक्शन (या सबरूटीन) सूचक का सरलतम कार्यान्वयन [[चर (कंप्यूटर विज्ञान)|वेरिएबल (कंप्यूटर विज्ञान)]] के रूप में होता है जिसमें निष्पादन योग्य मेमोरी के अंदर फ़ंक्शन का मेमोरी पता होता है। पुरानी तीसरी पीढ़ी की प्रोग्रामिंग लैंग्वेज | तीसरी पीढ़ी की लैंग्वेज जैसे पीएल/आई औरकोबोल, साथ ही अधिक आधुनिक लैंग्वेज जैसे [[पास्कल (प्रोग्रामिंग भाषा)|पास्कल (प्रोग्रामिंग लैंग्वेज)]] और सी (प्रोग्रामिंग लैंग्वेज) सामान्यतः इस तरह से फ़ंक्शन पॉइंटर्स को प्रयुक्त करती हैं।<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|# | |||
निम्नलिखित सी प्रोग्राम दो फ़ंक्शन पॉइंटर्स के उपयोग को दिखाता है: | निम्नलिखित सी प्रोग्राम दो फ़ंक्शन पॉइंटर्स के उपयोग को दिखाता है: | ||
* func1 एक डबल- | * func1 एक डबल-स्पष्ट (डबल) पैरामीटर लेता है और दूसरा डबल देता है, और फ़ंक्शन को समुनदेशित किया जाता है जो सेंटीमीटर को इंच में परिवर्तित करता है। | ||
* func2 | * func2 निरंतर वर्ण सरणी के साथ-साथ पूर्णांक के लिए सूचक लेता है और वर्ण को सूचक देता है, और एक सी स्ट्रिंग हैंडलिंग फ़ंक्शन को सौंपा जाता है जो किसी वर्ण सरणी में दिए गए वर्ण की पहली घटना के लिए सूचक देता है। | ||
<syntaxhighlight> | |||
#include <stdio.h> /* for printf */ | |||
#include <string.h> /* for strchr */ | |||
double cm_to_inches(double cm) { | |||
return cm / 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) { | |||
double (*func1)(double) = cm_to_inches; | |||
char * (*func2)(const char *, int) = strchr; | |||
printf("%f %s", func1(15.0), func2("Wikipedia", 'p')); | |||
/* 5.905512 | /* prints "5.905512 pedia" */ | ||
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> मानक आउटपुट द्वारा लिखा जाता है .<syntaxhighlight> | ||
# | #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 | 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; | |||
} | } | ||
</ | </syntaxhighlight> | ||
== फंक्टर्स == | == फंक्टर्स == | ||
{{main| | {{main|फंक्शन ऑब्जेक्ट}} | ||
फ़ंक्टर, या फ़ंक्शन ऑब्जेक्ट, फ़ंक्शन पॉइंटर्स के समान हैं, और समान | फ़ंक्टर, या फ़ंक्शन ऑब्जेक्ट, फ़ंक्शन पॉइंटर्स के समान हैं, और समान विधियों से उपयोग किए जा सकते हैं। फ़ंक्टर वर्ग प्रकार का ऑब्जेक्ट है जो [[फ़ंक्शन-कॉल ऑपरेटर]] को प्रयुक्त करता है, ऑब्जेक्ट को फ़ंक्शन कॉल के समान सिंटैक्स का उपयोग करके एक्सप्रेशन के अंदर उपयोग करने की अनुमति देता है। फ़ंक्टर साधारण फ़ंक्शन पॉइंटर्स की तुलना में अधिक शक्तिशाली होते हैं, अपने स्वयं के डेटा मान रखने में सक्षम होते हैं, और प्रोग्रामर को [[क्लोजर (कंप्यूटर प्रोग्रामिंग)]] का अनुकरण करने की अनुमति देते हैं। कॉलबैक फ़ंक्शन के रूप में सदस्य फ़ंक्शन का उपयोग करना आवश्यक होने पर उन्हें कॉलबैक फ़ंक्शन के रूप में भी उपयोग किया जाता है।<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> | ||
कई शुद्ध वस्तु-उन्मुख लैंग्वेज फ़ंक्शन पॉइंटर्स का समर्थन नहीं करती हैं। इस तरह की भाषाओं में कुछ समान प्रयुक्त किया जा सकता है, चूंकि, [[प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)]] के [[संदर्भ (कंप्यूटर विज्ञान)]] का उपयोग करके जो एकल [[विधि (कंप्यूटर प्रोग्रामिंग)]] (सदस्य फ़ंक्शन) को परिभाषित करता है। [[सीएलआई भाषाओं की सूची]] जैसे कि सी शार्प (प्रोग्रामिंग लैंग्वेज)|सी# और विज़ुअल बेसिक .नेट इम्प्लीमेंट [[प्रकार की सुरक्षा]]|सुरक्षा प्रकार के फंक्शन पॉइंटर्स विद डेलिगेट (सीएलआई) है। | |||
कार्यों को कॉल करने के लिए फ़ंक्शन पॉइंटर्स का व्यापक रूप से उपयोग आधुनिक प्रोसेसर पर कोड के लिए धीमा हो सकता है, क्योंकि | अन्य भाषाओं में जो प्रथम श्रेणी के कार्यों का समर्थन करते हैं, कार्यों को डेटा के रूप में माना जाता है, और फ़ंक्शन पॉइंटर्स की आवश्यकता को समाप्त करते हुए, अन्य कार्यों द्वारा प्रत्यक्ष पारित किया जा सकता है, लौटाया जा सकता है और गतिशील रूप से बनाया जा सकता है। | ||
कार्यों को कॉल करने के लिए फ़ंक्शन पॉइंटर्स का व्यापक रूप से उपयोग आधुनिक प्रोसेसर पर कोड के लिए धीमा हो सकता है, क्योंकि [[शाखा भविष्यवक्ता]] यह पता लगाने में सक्षम नहीं हो सकता है कि कहां शाखा करना है (यह कार्यसमय पर फ़ंक्शन पॉइंटर के मान पर निर्भर करता है) चूंकि इस प्रभाव को अतिरंजित किया जा सकता है क्योंकि अधिकांशतः गैर-अनुक्रमित तालिका लुकअप को अधिक कम करके इसकी आपूर्ति की जाती है। | |||
== विधि संकेत == | == विधि संकेत == | ||
सी ++ में ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग के लिए समर्थन सम्मिलित है, इसलिए कक्षाओं में विधि (कंप्यूटर प्रोग्रामिंग) हो सकती है (सामान्यतः सदस्य कार्यों के रूप में संदर्भित)। गैर-स्थैतिक सदस्य फ़ंक्शंस (इंस्टेंस मेथड्स) में निहित पैरामीटर ([[यह (कंप्यूटर प्रोग्रामिंग)]] पॉइंटर) होता है, जो उस ऑब्जेक्ट के लिए पॉइंटर होता है, जिस पर यह काम कर रहा है, इसलिए ऑब्जेक्ट के प्रकार को प्रकार के हिस्से के रूप में सम्मिलित किया जाना चाहिए। फ़ंक्शन सूचक। विधि का उपयोग उस वर्ग के ऑब्जेक्ट पर पॉइंटर-टू-सदस्य ऑपरेटरों में से एक का उपयोग करके किया जाता है: <code>.*</code> या <code>->*</code> (किसी वस्तु या वस्तु के सूचक के लिए क्रमशः)। | |||
चूंकि सी और सी ++ में फ़ंक्शन पॉइंटर्स को साधारण पते के रूप में प्रयुक्त किया जा सकता है, जिससे सामान्यतः <code>sizeof(Fx)==sizeof(void *)</code>, सी ++ में सदस्य पॉइंटर्स को कभी-कभी वसा पॉइंटर्स के रूप में कार्यान्वित किया जाता है, सामान्यतः वर्चुअल विधियों और वर्चुअल विरासत से निपटने के लिए साधारण फ़ंक्शन पॉइंटर के आकार के दो या तीन गुना होता है. | |||
< | ==== सी ++ में ==== | ||
# | सी ++ में, सी में उपयोग की जाने वाली विधि के अतिरिक्त, सी ++ मानक लाइब्रेरी क्लास टेम्पलेट का उपयोग करना भी संभव है {{mono|std::function}}, जिनमें से उदाहरण फ़ंक्शन ऑब्जेक्ट हैं:<syntaxhighlight> | ||
# | #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 << ] = << | std::cout << "d/dx(x ^ 2) [@ x = " << x << "] = " << derivative(f, x, 1e-5) << std::endl; | ||
return 0; | |||
} | } | ||
</ | </syntaxhighlight> | ||
=== सी ++ | ==== सी ++ में सदस्य कार्यों के लिए ==== | ||
{{See also|# | {{See also|#वैकल्पिक सी और सी ++ सिंटेक्स}} | ||
< | कक्षाओं या स्ट्रक्वेरिएबल्स के सदस्य कार्यों से निपटने के समय सी ++ फ़ंक्शन पॉइंटर्स का उपयोग करता है। इन्हें ऑब्जेक्ट पॉइंटर या इस कॉल का उपयोग करके बुलाया जाता है। वे इस प्रकार सुरक्षित हैं कि आप उस प्रकार के सूचक का उपयोग करके केवल उस वर्ग (या डेरिवेटिव) के सदस्यों को कॉल कर सकते हैं। यह उदाहरण सादगी के लिए जोड़े गए सदस्य फ़ंक्शन के सूचक के लिए टाइपपीफ के उपयोग को भी प्रदर्शित करता है। स्थैतिक सदस्य कार्यों के लिए फ़ंक्शन पॉइंटर्स पारंपरिक 'सी' शैली में किए जाते हैं क्योंकि इस कॉल के लिए कोई ऑब्जेक्ट पॉइंटर आवश्यक नहीं है।<syntaxhighlight> | ||
# | #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)) { | ||