2013-02-27 3 views
6

मुझे पॉइंटर्स का सिद्धांत विशेष रूप से परेशानी नहीं मिलती है, लेकिन मुझे कभी-कभी कुछ संकेतों से झुका हुआ है। निम्नलिखित उदाहरण में, कोई बता सकता है कि लाइन p = (int*) a कैसे काम करती है। कोड के मेरे पास स्पष्टीकरण से पता चलता है कि यह लाइन पॉइंटर पी में पहली सरणी के पहले तत्व के पते को संग्रहीत करती है, जैसे printf("%u", *p) उपज 5 उत्पन्न करती है। यदि यह मामला है तो यह लाइन p = a[0] लिखने का एक और अप्रत्यक्ष तरीका है?सूचक नोटेशन

int main() 
{ 
    int a[][4] = { 
     5, 7, 5, 9, 
     4, 6, 3, 1, 
     2, 9, 0, 6 
     }; 



    int *p; // create an integer pointer 
    int (*q)[4]; // create a pointer to a four-element integer array 

    p = (int*)a; // ? 
    q = a; 


    printf("%u %u\n", p, q); 
    p++; 
    q++; 
    printf("%u %u\n", p, q); 


    return 0; 
} 

उत्तर

7

अभिव्यक्ति a, जब मूल्य संदर्भ में प्रयोग किया , वास्तव में "a" के पहले तत्व के पते का मूल्यांकन करेगा - a[0] का पता - जैसा कि आपने इसे सही ढंग से समझा है।

हालांकि, ध्यान दें कि सरणी a वास्तव में हम 2D सरणी कहते हैं। यह सरणी के सरणी है। सरणी a का पहला तत्व स्वयं एक सरणी है: int [4] प्रकार की एक सरणी।इसलिए, उपरोक्त को ध्यान में रखते हुए, अभिव्यक्ति a, जब मान संदर्भ में उपयोग किया जाता है, अभिव्यक्ति &a[0] के समतुल्य है, जो कि int (*)[4] प्रकार का सूचक है और जो संपूर्ण 1D सर a[0] पर संकल्पनात्मक रूप से इंगित करता है।

इस कारण से, एक प्रयास

p = a; 

संकलक से एक नैदानिक ​​संदेश में परिणाम होगा करने के लिए। int (*)[4] मान int * पॉइंटर ऑब्जेक्ट को असाइन करना अवैध है। ये प्रकार संगत नहीं हैं। आदेश में इस नैदानिक ​​संदेश को दबाने के लिए में प्रश्न में कोड एक स्पष्ट डाली

p = (int *) a; 

यह जबरदस्ती p में ऊपर उल्लिखित int (*)[4] सूचक मूल्य shoves उपयोग करता है। एक सामान्य कार्यान्वयन में यह मूल सूचक के संख्यात्मक मूल्य को संरक्षित करता है, केवल एक वैचारिक प्रकार रूपांतरण करता है।

*p का मूल्य तक पहुँचने के लिए आम तौर पर a[0][0] बस क्योंकि संख्यानुसार पूरे a का पता का मूल्य का उत्पादन करेगा का प्रयास a[0] के पते के रूप में ही है और a[0][0] के पते के रूप में ही है। उपरोक्त कोड असंगतता के आसपास काम करने के लिए स्पष्ट कलाकार का उपयोग करते समय, इस संख्यात्मक पहचान का फायदा उठाता है।

+0

इस तरह के एक पूर्ण जवाब के लिए धन्यवाद। हालांकि मुझे पता था कि मैं 2-डी सरणी के साथ काम कर रहा था, मैंने सराहना नहीं की थी कि सूचक और एक [0] एक साधारण [int] सूचक के बजाय [इंट्स की सरणी] के लिए सूचक था। मैंने इस तथ्य को भी याद किया कि कुछ कास्टिंग चल रहा था। यह एक बहुत उपयोगी जवाब था। –

-2

aint के सरणी 4 की एक सरणी 3 है।

a का मान int के 4 के लिए एक सूचक है। इस सूचक का मूल्य सरणी की शुरुआत का पता है।

(int *) a पॉइंटर को पॉइंटर में int में परिवर्तित करता है। मान बदलता नहीं है लेकिन प्रकार अलग है।

ध्यान दें कि एक सूचक मूल्य मुद्रित करने के लिए, सही विनिर्देश p है।

+0

"का मान एक सूचक है" नहीं। 'ए' का मान एक सरणी है। – newacct

+0

@ न्यूवेक्ट सामान्य शब्दावली गलतफहमी। 'ए' एक सरणी है (मेरी पहली पंक्ति पढ़ें)। अब सरणी का * मान * अपने पहले तत्व के लिए एक सूचक है। ऑब्जेक्ट का मान वह है जो * * का मूल्यांकन करता है। सरणी के लिए ऑपरेटरों के अपवाद हैं जो उनके ऑपरेंड ('&' और 'sizeof') का मूल्यांकन नहीं करते हैं और एक वर्ण सरणी के लिए स्ट्रिंग अक्षर प्रारंभिक प्रारंभकर्ता का मूल्यांकन नहीं करते हैं। – ouah

+0

@ न्यूवाक्ट यदि आप उससे सहमत हैं, तो कृपया नीचे दिए गए – ouah

7

स्पष्टीकरण मैं कोड की है पता चलता है कि इस लाइन बस सूचक पी में पहली सरणी के पहले तत्व का पता संग्रहीत करता

सही।

यदि यह मामला है तो यह लाइन p = a[0] लिखने का एक और अप्रत्यक्ष तरीका है?

नहीं, ऐसा नहीं है। "इस लाइन बस संग्रहीत करता है पहला तत्व का पता" - यह बल्कि समान है

p = &a[0]; 

लिए लेकिन ऊपर बयान पूरी तरह से सही नहीं है, के बाद से &a[0] प्रकार int (*)[4] की है। एक डाली के बिना सही काम -Wall के साथ प्रयोग कर विभिन्न घोषणाओं के संकलन के साथ चारों ओर चालू तरह

p = &a[0][0]; 

प्ले कुछ हो सकता है और गूगल सकता है कभी कभी त्रुटियों/चेतावनी :)

+0

आपका उत्तर बहुत अच्छा है कि मैंने अपना हटा दिया। :) –

+0

@ruakh: नहीं, 2 डी-इंडेक्सिंग नीचे एक है - मैंने स्पष्टीकरण का विस्तार किया है। –

+0

@GrijeshChauhan :-) –

2

H2CO3 के जवाब पर विस्तार करने के लिए, याद रखें कि अधिकांश संदर्भों में सरणी की अभिव्यक्ति प्रकार सूचक प्रकार की अभिव्यक्ति में परिवर्तित हो जाएगा, और अभिव्यक्ति के मूल्य के पहले तत्व का पता हो जाएगा सरणी।

अभिव्यक्ति का प्रकार a "0 -की 4-तत्व सरणी का 3-तत्व सरणी है"। जब यह sizeof, _Alignof, या एकल & ऑपरेटरों के संकार्य है के अलावा, a(int (*)[4]) "int की 4-तत्व सरणी के लिए सूचक" प्रकार की अभिव्यक्ति के लिए परिवर्तित हो जाएगा, और इसके मूल्य का पता हो जाएगा a[0]। समस्या यह है कि int (*)[4] प्रकार का मान int * प्रकार के चर के लिए असाइन नहीं किया जा सकता है; प्रकार संगत नहीं हैं, इसलिए हमें a से int * अभिव्यक्ति का परिणाम डालना होगा।

यह काम करता है क्योंकि सरणी और सरणी के पहले तत्व का पता का पता एक ही है - भाव a, &a, a[0], &a[0], और &a[0][0] सब उपज ही मूल्य, वे सिर्फ अलग है प्रकार (int (*)[4], int (*)[4][4], int *, int (*)[4], और int * क्रमशः)।

+0

धन्यवाद भी। आप काफी सही हैं; प्रकार int (*) [4] और प्रकार int * के सूचक के बीच का अंतर मेरे लिए समाचार था, और कोड को समझने में मेरी विफलता के लिए केंद्रीय था। –

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