2010-08-05 12 views
9

क्या यह सही है?आप किसी फ़ंक्शन में पॉइंटर कैसे घोषित करते हैं जो सी/सी ++ में int मानों की सरणी में पॉइंटर देता है?

int (*(*ptr)())[]; 

मैं जानता हूँ कि यह तुच्छ है, लेकिन मैं निर्माणों इस तरह के बारे में एक पुरानी परीक्षण देख रहा था, और इस विशेष संयोजन परीक्षण पर नहीं था और यह वास्तव में मुझे पागल गाड़ी चला रहा है; मुझे बस यह सुनिश्चित करना है। क्या इस तरह की घोषणाओं के लिए कोई स्पष्ट और ठोस समझने योग्य नियम है? (यानी: पॉइंटर टू ... सरणी .. पॉइंटर्स ... फ़ंक्शंस .... आदि आदि) धन्यवाद!

आर

+4

+1 प्रमुख शीर्षक के लिए जो मेरे दिमाग को चोट पहुंचाता है! (इसके अलावा नाम: पी) – Russell

+0

शायद यह एक उत्तर बना सकता है, लेकिन घड़ी के सर्पिल नियम को याद रखें, यह दोनों तरीकों से काम करता है, बस दिशा के लिए समायोजित करें। – jer

+0

बढ़ावा है :: फ़ंक्शन कुछ जिसे आप स्वीकार करेंगे? –

उत्तर

13

The right-left rule आसान बनाता है।

int (*(*ptr)())[]; चर नाम से के रूप में

प्रारंभ व्याख्या की जा सकती ------------------------------- ptr

सही करने के लिए कुछ भी नहीं है लेकिन ) तो * -------------- खोजने के लिए छोड़ दिया जाने कोष्ठकों से बाहर

कूद एक सूचक है और () मुठभेड़ --- -------- एक फ़ंक्शन के लिए कोई तर्क नहीं लेता है (सी के अनिर्दिष्ट संख्या के मामले में)

छोड़ें, * --------------------------- --------------------- और एक सूचक

कोष्ठक डालें, दाएं जाएं और [] ---------

पर जाएं, फिर से जाएं, int --------------------------------- ---- ints

+3

इस बारे में कुछ भी आसान नहीं है। मैं इसे थोड़ा तोड़ने के लिए टाइपपीफ का उपयोग करना पसंद करता हूं। –

+0

ध्यान दें कि उदाहरण वैध घोषणा नहीं है - इसे बनाने के लिए, सरणी आकार को निर्दिष्ट करने की आवश्यकता है। – caf

+2

@caf: यह प्रकार को अधूरा प्रकार बनाता है लेकिन आप अभी भी एक घोषणा में एक अपूर्ण प्रकार के लिए सूचक का उपयोग कर सकते हैं। –

0

यहाँ मेरी समाधान है ...

int** (*func)(); 

functor पूर्णांक * के की एक सरणी लौटने। यह आपके समाधान के रूप में जटिल नहीं है।

1

cdecl आप निम्नलिखित मिल

cdecl> declare a as pointer to function returning pointer to array of int; 
Warning: Unsupported in C -- 'Pointer to array of unspecified dimension' 
    (maybe you mean "pointer to object") 
int (*(*a)())[] 

This question सी फैक से उपयोग करना समान है, लेकिन समस्या का समाधान करने के लिए 3 दृष्टिकोण प्रदान करता है।

5

लगभग सभी स्थितियों में, जहां आप ऐसा करने का सरलतम बात एक सरणी के लिए सूचक लौटना चाहते में सरणी के पहले तत्व के लिए सूचक वापस जाने के लिए है। इस सूचक का एक ही संदर्भ में एक सरणी नाम के रूप में उपयोग किया जा सकता है जो "पॉइंटर टू सरणी" प्रकार के सूचक को लौटने से अधिक या कम संकेत नहीं देता है, वास्तव में यह वही सूचक मूल्य रखेगा।

आप इस का पालन करें आप एक int के लिए सूचक वाला फ़ंक्शन करने के लिए एक सूचक चाहते हैं। आप इसे बना सकते हैं (घोषणाओं का निर्माण पार्सिंग से आसान है)।

सूचक int रहे हैं:

int *A; 

समारोह लौटने सूचक int रहे हैं:

int *fn(); 

एक सूचक लौटने कार्य करने के लिए सूचक int रहे हैं:

int *(*pfn)(); 

यदि आप वास्तव में int की एक सरणी में पॉइंटर लौटने वाले फ़ंक्शन में पॉइंटर वापस करना चाहते हैं तो आप उसी प्रक्रिया का पालन कर सकते हैं। int की

सरणी:

int A[]; 

int की सरणी सूचक:

int (*p)[]; 

समारोह लौटने सूचक ...:

int (*fn())[]; 

सूचक fn के लिए ...:

int (*(*pfn)())[]; 

जो आपके पास है।

1

आप धोखाधड़ी की तरह महसूस करते हैं:

typedef int(*PtrToArray)[5]; 
PtrToArray function(); 

int i = function; 

कि जीसीसी पैदावार पर संकलन: invalid conversion from 'int (*(*)())[5]' to 'int'। पहला बिट वह प्रकार है जिसे आप ढूंढ रहे हैं।

बेशक

, एक बार आप अपने PtrToArray typedef है, पूरी कवायद बल्कि अधिक तुच्छ हो जाता है, लेकिन कभी कभी इस काम में आता है, तो आप पहले से ही समारोह नाम है और आप बस इसे कहीं छड़ी की जरूरत है। और, किसी भी कारण से, आप अपने द्वारा गोरियों के विवरण छिपाने के लिए टेम्पलेट चालबाजी पर भरोसा नहीं कर सकते हैं।

अपने संकलक इसका समर्थन करता है, तो आप भी ऐसा कर सकते हैं: प्रकार पढ़ने में सक्षम होने के नाते

typedef int(*PtrToArray)[5]; 
PtrToArray function(); 

template<typename T> void print(T) { 
    cout << __PRETTY_FUNCTION__ << endl; 
} 

print(function); 

कौन सा, मेरे कंप्यूटर बॉक्स पर, पैदा करता है void function(T) [with T = int (* (*)())[5]]

, सुंदर उपयोगी है संकलक त्रुटियों को समझने के बाद से अक्सर उन सभी कोष्ठक का अर्थ समझने की आपकी क्षमता पर निर्भर करता है। लेकिन उन्हें स्वयं बनाना कम उपयोगी है, आईएमओ।

2

आप नहीं करते हैं। बस इसे दो typedefs में विभाजित करें: एक सूचक के लिए int सरणी के लिए, और एक सूचक के लिए काम करने के लिए। कुछ की तरह:

typedef int (*IntArrayPtr_t)[]; 
typedef IntArrayPtr_t (*GetIntArrayFuncPtr_t)(void); 

यह न केवल अधिक पठनीय है, यह भी यह आसान घोषणा/कार्यों कि चर निर्दिष्ट करने जा रहे हैं परिभाषित करने के लिए बनाता है:

IntArrayPtr_t GetColumnSums(void) 
{ .... } 
बेशक

इस मान लिया गया यह था एक वास्तविक दुनिया की स्थिति, और एक साक्षात्कार प्रश्न या होमवर्क नहीं। मैं अभी भी तर्क दूंगा कि यह उन मामलों के लिए एक बेहतर समाधान है, लेकिन यह केवल मुझे है।:)