2011-07-21 13 views
5

इम काफी उलझन में है कि इन दो initializations के बीच अंतर क्या है:सी सूचक सरणी Initializtion

int (*p)[10]; 

और

int *p[10] 

मैं जानता हूँ कि वे दोनों 2 डी सरणी जिसका तत्व पंक्ति में गिनती 10 को इंगित कर सकते हैं ....

+0

सी ++ - एफएसी पोस्ट में कुछ विस्तार से चर्चा की गई (जिनमें से कई सी पर भी लागू होते हैं): http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c – Cubbi

+0

http: // cdecl।संगठन – sidyll

उत्तर

2

यहाँ पहले से ही सही जवाब पर थोड़ा विस्तार से बता दें:

प्रथम पंक्ति:

int (*p)[10]; 

घोषणा करता है कि "पी" 10 की क्षमता के साथ एक सरणी की स्मृति पते के लिए सूचक है ints। इसे अंग्रेजी में पढ़ा जा सकता है: "पूर्णांक-सूचक 'पी' स्मृति में 10 क्रमिक इनट्स को इंगित करता है"।

दूसरी पंक्ति:

int *p[10] 

घोषणा करता है कि "पी []" पूर्णांकों के लिए 10 संकेत की एक सरणी है। यह स्मृति पते की एक सरणी है जो पूर्णांक को इंगित करती है। इस मामले में, "पी" स्मृति में 10 पॉइंटर्स का अनुक्रम है (जो अन्य चींटियों के मेमोरी पते होते हैं)।

+0

अच्छा !! Thnx !! यह मेरे संदेह को साफ़ करता है .... – kHAzaDOOm

+1

दूसरे मामले के लिए, मुझे लगता है कि आप "पी" -इस- स्मृति में 10 पॉइंटर्स का अनुक्रम (जो कि इट्स के मेमोरी पते होते हैं) का कहना है। –

+0

हाँ! गलतफहमी के लिए खेद है। – AlexFZ

0

पहले परिभाषा (प्रारंभिकरण नहीं), p एक सूचक है; दूसरे में, p 10 पॉइंटर्स की एक सरणी है।

+0

क्या आप दोनों को अलग-अलग उदाहरण प्रदान कर सकते हैं .... – kHAzaDOOm

+1

दोनों परिभाषाओं के लिए 'sizeof p' आज़माएं :-) – pmg

4

पहला सरणी के लिए एक सूचक है, दूसरा पॉइंटर्स की एक सरणी है।

1

आपके पहले उदाहरण में, पी 10 पूर्णांक की सरणी के लिए सूचक है। दूसरे उदाहरण में, पी 10 पॉइंटर्स की एक सरणी है।

आप निम्नानुसार "दस int की सरणी के लिए सूचक" प्रकार की ऑब्जेक्ट आवंटित कर सकते हैं।

int (**ptr)[10] = new (int (*)[10]); 

ध्यान दें, किसी भी ints के लिए कोई जगह आवंटित किया जाता है; केवल सूचक ही।

आप 10 ints की एक सरणी के रूप में निम्नानुसार आवंटित कर सकते हैं:

int *ptr = new int[10];

(स्पष्ट कास्टिंग के बिना) आप ऐसा नहीं कर सकते क्या एक सूचक करने के लिए 10 int की एक गतिशील आवंटित सरणी के लिए सूचक आवंटित int (*)[10] टाइप करें। जब भी आप नए के माध्यम से एक सरणी आवंटित करते हैं, भले ही आप typedef का उपयोग करते हैं, नई अभिव्यक्ति का प्रकार सरणी के पहले तत्व के लिए एक सूचक है; सरणी का आकार नई अभिव्यक्ति के प्रकार में नहीं रखा जाता है।

ऐसा इसलिए है क्योंकि new[] अभिव्यक्तियां उन सरणी आवंटित कर सकती हैं जहां सरणी का आकार रनटाइम पर चुना जाता है, इसलिए नई अभिव्यक्ति के प्रकार में सरणी आकार को एन्कोड करने के लिए हमेशा संभव नहीं होगा (या यहां तक ​​कि वांछनीय)।

जैसा कि सुझाव दिया गया है, आप गतिशील रूप से 10 int की एक सरणी को सरणीकृत कर सकते हैं। पहली सरणी का आकार प्रकार की जानकारी से खो जाता है और आपको जो मिलता है वह चार int के सरणी के सरणी (आकार 1) के पहले तत्व के लिए सूचक होता है।

int (*p)[10] = new int[1][10]; 

भले ही यह सिर्फ 1 (10 int की सरणियों) की एक सरणी है, तब भी आप delete[] उपयोग करने के लिए p पुनःआवंटन की जरूरत है।

delete[] p;

बेशक एक वास्तव में एक पद के लिए मैन्युअल रूप से हटाने के कॉल करने की आवश्यकता करने के लिए कभी नहीं करना चाहिए।

2
int (*p)[10]; 


+------+       +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ 
| p | =========================>|(*p)[0]|(*p)[1]|(*p)[2]|(*p)[3]|(*p)[4]|(*p)[5]|(*p)[6]|(*p)[7]|(*p)[8]|(*p)[9]| 
+------+       +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ 

sizeof psizeof (void *) (4 32 पर बिट सिस्टम, 8 64 पर बिट सिस्टम)

sizeof *p वापस आ जाएगी 10*sizeof (int) (40 सबसे सिस्टम पर) वापस आ जाएगी

int *p[10]; is the same as  int* (p[10]); 

p 
+------+------+------+------+------+------+------+------+------+------+ 
| p[0] | p[1] | p[2] | p[3] | p[4] | p[5] | p[6] | p[7] | p[8] | p[9] | 
+------+------+------+------+------+------+------+------+------+------+ 

sizeof p10*sizeof (void *) वापस आ जाएगी (32 बिट सिस्टम पर 40, 64 बिट सिस्टम पर 80)

sizeof *psizeof (int *) (4 32 पर बिट सिस्टम, 8 64 पर बिट सिस्टम)

+0

बस टिप्पणी करना और इस उत्तर की गहराई और विस्तार पर आपको सराहना करना चाहता था। ASCII चित्रों पर जाएं! – AlexFZ

0

वापस आ जाएगी जैसा कि अन्य लोगों ने बताया है, int (*p)[10]int के एक 10 तत्व सरणी के सूचक के रूप p वाणी है, जबकि int *p[10] एक 10- रूप p वाणी पॉइंटर का तत्व सरणी int पर।

सी में, घोषणाओं भाव, नहीं वस्तुओं के प्रकार के चारों ओर बनाया जाता है। विचार यह है कि घोषणा का रूप अभिव्यक्ति के रूप से मेल खाना चाहिए क्योंकि यह कोड में उपयोग किया जाता है।

मान लीजिए कि pint की ओर इशारा की एक सरणी (दूसरे मामले) है। एक विशेष पूर्णांक मान पहुंचने के लिए, आप सरणी में और परिणाम भिन्नता सबस्क्रिप्ट चाहते हैं, के रूप में में

x = *p[i]; 
[] और () तरह

पोस्टफिक्स ऑपरेटरों, * की तरह एकल ऑपरेटरों की तुलना में अधिक पूर्वता है तो उपरोक्त कथन के रूप में पार्स किया गया है *(p[i]) (आईओओ, * अभिव्यक्ति p[i] पर लागू होता है)।

अभिव्यक्ति*p[i]int है के प्रकार, तो p की इसी घोषणा int *p[10]; है।

अब मान लें कि p int (पहले मामले) की एक सरणी के लिए एक सूचक है। एक विशेष पूर्णांक मान पहुंचने के लिए, आप, संकेतक भिन्नता चाहते हैं और फिर परिणाम सबस्क्रिप्ट,

x = (*p)[i]; 

फिर में के रूप में क्योंकि []* की तुलना में अधिक पूर्वता है, हम कोष्ठक का उपयोग करने के लिए स्पष्ट रूप से बस के साथ * संबद्ध करने की आवश्यकता p, p[i] नहीं। (*p)[i] अभिव्यक्ति का प्रकार int है, इसलिए p की घोषणा int (*p)[10]; है।

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