2012-06-04 31 views
6

हैलो फ्रेंड्स,
How can I use an array of function pointers?
यदि हम उपर्युक्त लिंक देखेंगे, तो यह हमें बताता है कि पॉइंटर फ़ंक्शन कैसे काम करता है।
अब सवाल यह है कि मुझे फ़ंक्शन पॉइंटर क्यों चुनना चाहिए?
मैं फ़ंक्शन कॉल का उपयोग क्यों नहीं कर सकता?
फ़ंक्शन पॉइंटर के साथ मुझे क्या लाभ मिलेगा?
जैसेफ़ंक्शन पॉइंटर बनाम फ़ंक्शन कॉल के बीच क्या अंतर है?

enum{a, b, c}; 
void A(); 
void B(); 
void C(); 
void (*fun[3])() = {A, B, C}; 

Now when I need to call a function I am doing like, 
fun[a](); // This calls function A 
// And so on... 

एक ही समारोह में किया जा सकता है जब मैं क्यों फिर समारोह ए, बी या सी सीधे मैं सही तरह से कर सकते हैं

A(); 
B(); 
or 
C(); 

कॉल करने की आवश्यकता भी

कॉल function pointer?

+2

मुझे नहीं पता कि मेरे प्रश्न के दो नकारात्मक वोट क्यों हैं। लेकिन एक बात मुझे पता है, इसका मतलब यह नहीं है कि अगर आप कुछ जानते हैं कि हर किसी को जानना चाहिए। किसी भी तरह + या वोट वोट तब तक कोई फर्क नहीं पड़ता जब तक मेरे संदेह साफ नहीं हो जाते। –

उत्तर

5

अब सवाल यह है कि मुझे फ़ंक्शन पॉइंटर क्यों चुनना चाहिए?
फ़ंक्शन पॉइंटर के साथ मुझे क्या लाभ मिलेगा?

जब आप एक असीमित तंत्र को लागू करने की आवश्यकता होती है तो आप फ़ंक्शन पॉइंटर्स का उपयोग करते हैं।
आपको कुछ होता है जब आपको एक फ़ंक्शन को असीमित रूप से कॉल करने की आवश्यकता होती है।
आपको कैसे पता चलेगा कि कौन सा फ़ंक्शन कॉल करना है?
प्रत्येक फ़ंक्शन का पता अद्वितीय है, इसलिए आपको फ़ंक्शन पता का उपयोग और स्टोर करने की आवश्यकता है।
आप इस फ़ंक्शन पते को कहां स्टोर करते हैं?
एक समारोह सूचक

2

फ़ंक्शन पॉइंटर्स पॉइंटर्स (चर परिवर्तक की तरह) हैं जो फ़ंक्शन के पते पर इंगित करते हैं। वे वास्तव में अंतर्निहित फ़ंक्शन को कॉल करते हैं जब आप उन्हें फ़ंक्शन कॉल की तरह मानते हैं।

एक समारोह सूचक का मुख्य लाभ यह है कि आप एक पैरामीटर उदाहरण के लिए के रूप में एक और कार्य करने के लिए इसे पारित कर सकते हैं ...

3

मेरे अनुभव में, समारोह संकेत मुख्य रूप से एक पैरामीटर के रूप में एक समारोह पारित करने के लिए उपयोग किया जाता है एक और समारोह के लिए।

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

11

वहाँ सी

में सामान्य रूप से काम करने के लिए विशेष रूप से, एक समारोह सूचक का उपयोग करने के कई कारण मुख्य जगह आप उन्हें इस्तेमाल किया जा रहा देखेंगे के लिए एक तर्क के रूप में कर रहे हैं एक समारोह।समारोह bsearch साथ उदाहरण के लिए, यह एक तुलना समारोह, एक समारोह सूचक के रूप में पारित कर दिया, आइटम की तुलना और डेटा को सॉर्ट करने का उपयोग करता है:

void *bsearch(const void *key, const void *base, 
        size_t nmemb, size_t size, 
        int (*compar)(const void *, const void *)); 

bsearch सामान्य हो सकता है और डेटा के किसी भी प्रकार को सॉर्ट करने की अनुमति देता है यही कारण है, केवल कि जब तुलनात्मक कार्य को डेटा के प्रकार को जानना है।


एक और को एकाधिक चेक से बचने के साथ करना है। अर्थात।

void makePizza(void) { } 

void bakeCake(void) { } 

iWantPizza = 1; 
... 
if (iWantPizza) 
    makePizza(); 
else 
    bakeCake(); 
/* want to call the same function again... */ 
if (iWantPizza) 
    makePizza(); 
else 
    bakeCake(); 

.. 

/* alternative */ 
void (*makeFood)(void) = iWantPizza ? makePizza : bakeCake; 

makeFood(); 
/* want to call the same function again... */ 
makeFood(); 
6

उदाहरण के लिए, आपने एक और चीज की जा सकती है।

आइए कहें कि फ़ंक्शन का समूह है जिसे कुछ डिवाइस ऑपरेशन के लिए चलाने की आवश्यकता है। सरल तरीके से, आप किसी अन्य मास्टर फ़ंक्शन में सभी फ़ंक्शन कॉल लिख सकते हैं और मास्टर फ़ंक्शन पर कॉल कर सकते हैं।

ऐसा करने का एक और तरीका है, सभी फ़ंक्शन नामों को घुंघराले ब्रैकेट में लिखें और फ़ंक्शन पॉइंटर और लूप का उपयोग करके प्रत्येक को कॉल करें। यह स्मार्ट दिखता है। मुझे यकीन नहीं है कि यह आपको बेहतर तरीके से कैसे मदद करता है लेकिन मैंने इसे लिनक्स कर्नेल कोड में देखा।


मैं यहां सभी उत्तरों से सहमत हूं। इसके अलावा मेरे पास फ़ंक्शन पॉइंटर का उपयोग करने के लिए मेरे कुछ निर्णय हैं।

चलिए कुछ जटिल गणित की गणना का उदाहरण लें (जैसे फिबोनाची, एकीकरण, चौकोर एक्सफॉर्म, आदि प्रिंटिंग ...)।

आपके पास एक फ़ंक्शन FX है (जो जटिल गणित गणना या कुछ और करता है) जिसे आप अपने प्रोग्राम में कई बार उपयोग करते हैं। यह फ़ंक्शन कई अलग-अलग नौकरियों में उपयोग किया जाता है।

कुछ महीनों के लिए अपने प्रोग्राम का उपयोग करने के बाद, आप पाते हैं कि, कुछ कामों के लिए, आप फ़ंक्शन को बेहतर बना सकते हैं और कुछ के लिए, वर्तमान में सबसे अच्छा है। आप क्या करेंगे? एक नया फ़ंक्शन लिखें, सभी जगहों पर फ़ंक्शन का नाम बदलें और बदलें।

हर बार जब आप कुछ बेहतर पाते हैं, तो आप वही करेंगे।

इसके बजाय, विभिन्न कार्यों के लिए विभिन्न फ़ंक्शन पॉइंटर का उपयोग करें। प्रारंभिक चरण में, सभी पॉइंटर्स एक फ़ंक्शन को इंगित कर सकते हैं। जब आप कुछ काम के लिए बेहतर काम खोजते हैं, तो बस पॉइंटर को हटा दें और आप कर लेंगे।


एक और परिदृश्य लें। यहां, आपके पास मोबाइल फोन ओएस जैसे वास्तविक बड़े कोड हैं। (पूरी तरह से खुला नहीं है लेकिन आधा संकलित)। आपको किसी विशेष हार्डवेयर के लिए ब्लूटूथ ड्राइवर जोड़ने की आवश्यकता है।

अब, आप जोड़ सकते हैं या छोड़ सकते हैं ओएस में उपलब्ध विकल्प है।

आपको कई स्थानों से ब्लूटूथ चालू/बंद करना पड़ सकता है।

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

यह वही है जो मैंने पहले ही एंड्रॉइड ओएस के तहत देखा है।(बिल्कुल नहीं बल्कि निकट)

+1

मुझे जटिल गणित की गणना के साथ वास्तव में उदाहरण पसंद है। – johnny

3

फ़ंक्शन पॉइंटर बनाम फ़ंक्शन कॉल के बीच क्या अंतर है?

यह संकलक पूछ करने के लिए बीच का अंतर की तरह है बजाय "मेरे लिए ले" मुझे नेशनल गैलरी के पते बता (मैं बाद में वहाँ जाने के लिए चाहते हो सकता है और मैं इसे करने के लिए तैयार होना चाहता हूँ) ", नेशनल गैलरी अभी (लेकिन मैं इस पर ध्यान नहीं दे रहा हूं कि आप मुझे वहां कैसे पहुंचे हैं इसलिए मुझे बाद में जानने की उम्मीद न करें) "। महत्वपूर्ण बात यह है कि यदि आप पता/सूचक के लिए पूछते हैं तो आप इसे "अगले रविवार दोपहर की बड़ी यात्रा" जैसी जगह पर लिख सकते हैं ... आपको यह भी याद रखना नहीं है कि यह राष्ट्रीय गैलरी है जिसे आप जा रहे हैं - जब आप वहां जाते हैं तो यह एक सुखद आश्चर्य हो सकता है - लेकिन आप तुरंत अपने रविवार के मनोरंजन को सभी तरह से जानते हैं।

फ़ंक्शन पॉइंटर के साथ मुझे क्या लाभ मिलेगा?

ठीक है, जैसा कि ऊपर, समय आप समारोह सूचक आप जहां बाद में फोन करता हूँ के बारे में निर्णय करने के लिए की जरूरत है निर्धारित करते हैं, लेकिन फिर आपको लगता है कि निर्णय लेने के लिए सभी कारणों के बारे में भूल कर सकते हैं और सिर्फ इतना पता है कि बाद में गंतव्य उपयोग के लिए तैयार है। उस समय जब आप वास्तव में सामान कर रहे हैं ... "मेरी रविवार की दिनचर्या: 10 में सो जाओ, एक बड़ा नाश्ता खाएं, बिस्तर पर वापस जाएं, स्नान करें, अगर मेरे पास बहुत पैसा है तो मेरे रविवार को जाएं दोपहर की बड़ी यात्रा, रात्रिभोज के लिए दोस्तों से मिलें "... पहले निर्णय आपको गैलरी में लाने के लिए बस जाता है। महत्वपूर्ण बात यह है कि आप अपने परिचित रविवार के शेड्यूल का उपयोग जारी रख सकते हैं और "अपनी रविवार की दोपहर की बड़ी यात्रा" पता/पॉइंटर को नए स्थानों पर "पॉइंटिंग" शुरू कर सकते हैं क्योंकि वे आपकी आंखें पकड़ते हैं, भले ही वे आपके सामान्य शेड्यूल के गठन के दौरान मौजूद न हों।

आप एएससीब्लॉक के bsearch के उल्लेख से अच्छी तरह से चित्रित पुराने दिनचर्या में एक चरण में प्रेषित गंतव्य को बदलने के लिए इस पोस्ट-फैक्टो लचीलापन को देखते हैं। qsort एक और क्लासिक उदाहरण है - यह मनमाने ढंग से चीजों के सरणी को कुशलतापूर्वक सॉर्ट करने का बड़ा चित्र तर्क जानता है, लेकिन यह बताया जाना चाहिए कि आप वास्तव में इसका उपयोग करने वाली दो चीज़ों की तुलना करने के लिए कहां जाना है।

1

ये अच्छे उदाहरण हैं, खासकर उर्विश के ऊपर में पहला। मैंने वही बात सोच ली है, और मुझे लगता है कि जवाब पूरी तरह डिजाइन है। मेरे दिमाग में, वे एक ही परिणाम हैं, जैसा कि आप एक समारोह को इंगित कर सकते हैं और एक + बी प्राप्त कर सकते हैं या आप नियमित रूप से एक फ़ंक्शन को कॉल कर सकते हैं और एक + बी प्राप्त कर सकते हैं, और SO पर उदाहरणों के साथ, वे आमतौर पर छोटे और छोटे होते हैं चित्रण के लिए। लेकिन, अगर किसी के पास 10k लाइन सी प्रोग्राम था, और आपको कुछ पचास बार बदलना पड़ा क्योंकि आपने बदलाव किया था, तो आप संभवतः बहुत तेज़ी से उठाएंगे कि आप फ़ंक्शन पॉइंटर्स का उपयोग क्यों करना चाहते हैं।

यह आपको ओओपी भाषाओं के डिजाइन और ओओडी के पीछे दर्शन की सराहना करता है।

संबंधित मुद्दे