2011-10-06 6 views
11

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

मुझे यकीन नहीं है कि यह कैसे करें और काम करने वाली किसी भी चीज़ के पास कहीं भी न आएं।

यहां कुछ उदाहरण कार्यों है:

add(int x, int y) { 
    return x+y; 
} 

और,

mean(int x1, int y1, int x2, int y2) { 
    return (x1 + y1 + x2 + y2)/4; 
} 

अब तक मैं दोनों के साथ typedef का उपयोग कर की कोशिश की है, लेकिन मैं समझ नहीं सकता कैसे में से एक के लिए कुछ बिंदु बनाने के लिए या तो टाइप करें:

typedef int (*mathfunc2)(int x, int y); 
typedef int (*mathfunc4)(int x1, int y1, int x2, int y2); 

????? func_table[2] = {add, mean}; 

उत्तर

25

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

दूसरे शब्दों में:

typedef int (*generic_fp)(void); 

generic_fp func_table[2] = { (generic_fp)add, (generic_fp)mean }; 

फिर add कॉल करने के लिए, आप सही प्रकार के लिए इसे वापस कास्ट करने के लिए की जरूरत है:

result = ((mathfunc2)func_table[0])(x, y); 

आप कुछ मैक्रो भी निर्धारित कर सकते हैं यदि आप इसे अधिक स्वादिष्ट लगता है:

#define FUNC_2(f, p1, p2) ((mathfunc2)(f))(p1, p2) 
#define FUNC_4(f, p1, p2, p3, p4) ((mathfunc4)(f))(p1, p2, p3, p4) 

result = FUNC_2(func_table[0], x, y); 
+0

यह वास्तव में चाल है! धन्यवाद एक गुच्छा, महोदय। मुझे उम्मीद है कि अगर मुझे कभी 15 प्रतिष्ठा मिलती है और आपको एक तीर देता है :) – vaughanj

+0

मैं इंप्रेशन फ़ंक्शन पॉइंटर्स के तहत पैरामीटर के कारण नियमित शून्य पॉइंटर्स से अलग व्यवहार करता था। कि आप फ़ंक्शन पॉइंटर्स को विभिन्न पैरामीटर के साथ मिश्रित नहीं कर सके क्योंकि स्टैक क्लीनअप पर दूषित हो जाएगा। क्या मैंने कुछ गलत समझा है? – Ioan

+0

@Ioan: आपको फ़ंक्शन को घोषित प्रकार के साथ संगत एक पॉइंटर के माध्यम से कॉल करना होगा - जिसका अर्थ यह है कि यदि आप फ़ंक्शन पॉइंटर को स्टोरेज के लिए किसी भिन्न प्रकार में डालते हैं, तो आपको इसे सही प्रकार पर कॉल करने के लिए सही तरीके से डालना होगा कार्यक्रम। इस जवाब में उदाहरण यह करता है। – caf

0

ये दो फ़ंक्शन प्रकार असंगत हैं। कड़ाई से बोलते हुए, उन्हें पूरी तरह से अलग बहस का उपयोग करके कार्यान्वित किया जा सकता है। एक कार्यान्वयन चुन सकता है, उदाहरण के लिए, 3 पैरामीटर वाले सभी फ़ंक्शंस उन्हें रजिस्टरों के माध्यम से प्राप्त करते हैं, और अन्य सभी फ़ंक्शंस उन्हें स्टैक के माध्यम से प्राप्त करते हैं।

क्या आप ऐसा कर सकते हैं, हालांकि के साथ दोनों कार्यों को परिभाषित करने के लिए है उन्हें एक ही पैरामीटर गुजर योजना का पालन करते हैं मापदंडों varargs।

आप इन कार्यों को वैसे भी कॉल करने का इरादा कैसे रखते थे, यह नहीं जानते कि वे कितने पैरामीटर की अपेक्षा करते हैं?

3

आप Facade Pattern इस तरह इस्तेमाल कर सकते हैं:

int add(int x, int y); 
int mean(int x1, int y1, int x2, int y2); 

typedef int (*operation_fp)(int argc, int* argv); 

int add_wrapper(int argc, int* argv) { return add(argv[0], argv[1]); } 
int mean_wrapper(int argc, int* argv) { return mean(argv[0], argv[1], argv[2], argv[3]); } 

operation_fp func_table[2] = { add_wrapper, mean_wrapper }; 

हालांकि कोड बदसूरत है, यह काम करता है। आपको रैपर में कुछ सत्यापन तर्क जोड़ना चाहिए।

1
int (*func[])() = { add, mean }; 
+0

प्रकार 'int (*) (int, int) 'और' int (*) (int, int, int, int) प्रकार के फ़ंक्शन पॉइंटर्स 'int * * (int) प्रकार के फ़ंक्शन पॉइंटर्स के साथ संगत नहीं हैं * int, ...) '। – caf

+0

सुनिश्चित करें,() में संपादित करें – BLUEPIXY

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

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