अन्य उत्तर सही हैं, लेकिन उनमें से कोई भी इस विचार पर जोर नहीं देता है कि तीनों के लिए समान मूल्य शामिल है , और इसलिए वे किसी तरह से अधूरे हैं।
इसका कारण अन्य उत्तरों से नहीं समझा जा सकता है कि सभी चित्रण, जबकि सहायक और निश्चित रूप से अधिकांश परिस्थितियों में उचित हैं, उस स्थिति को कवर करने में विफल होते हैं जहां सूचक x
खुद को इंगित करता है।
यह निर्माण करना बहुत आसान है, लेकिन स्पष्ट रूप से समझने में थोड़ा कठिन है। नीचे दिए गए कार्यक्रम में, हम देखेंगे कि कैसे हम तीनों मूल्यों को समान होने के लिए बाध्य कर सकते हैं।
नोट: इस कार्यक्रम में व्यवहार अपरिभाषित है, लेकिन मैं इसे विशुद्ध रूप से किसी ऐसी चीज़ के एक दिलचस्प प्रदर्शन के रूप में पोस्ट कर रहा हूं जो पॉइंटर्स कर सकते हैं, लेकिन ऐसा नहीं करना चाहिए ।
#include <stdio.h>
int main () {
int *(*x)[5];
x = (int *(*)[5]) &x;
printf("%p\n", x[0]);
printf("%p\n", x[0][0]);
printf("%p\n", x[0][0][0]);
}
यह C89 और C99 दोनों में चेतावनी के बिना संकलित करता है, और आउटपुट निम्न है:
$ ./ptrs
0xbfd9198c
0xbfd9198c
0xbfd9198c
दिलचस्प रूप से पर्याप्त है, तीनों मूल्य समान हैं। लेकिन यह एक आश्चर्य नहीं होना चाहिए! सबसे पहले, चलो कार्यक्रम को तोड़ते हैं।
हम x
5 तत्वों की एक सरणी के लिए एक पॉइंटर के रूप में घोषित करते हैं, जहां प्रत्येक तत्व इंट के लिए टाइप पॉइंटर का है। यह घोषणा रनटाइम स्टैक पर 4 बाइट्स आवंटित करती है (या आपके कार्यान्वयन के आधार पर और अधिक; मेरे मशीन पॉइंटर्स 4 बाइट्स पर हैं), इसलिए x
एक वास्तविक मेमोरी लोकेशन का जिक्र है। भाषाओं के सी परिवार में, सामग्री x
केवल कचरा है, स्थान के पिछले उपयोग से कुछ बचा है, इसलिए x
स्वयं कहीं भी इंगित नहीं करता है - निश्चित रूप से आवंटित स्थान पर नहीं।
इसलिए, स्वाभाविक रूप से, हम चर का पता ले सकते हैं x
और इसे कहीं रख सकते हैं, इसलिए ठीक यही हम करते हैं। लेकिन हम आगे बढ़ेंगे और इसे x में डाल देंगे। चूंकि &x
एक अलग प्रकार है x
, इसलिए हमें एक कास्ट करने की आवश्यकता है ताकि हमें चेतावनी न मिले।
मेमोरी मॉडल कुछ इस तरह दिखाई देगा:
0xbfd9198c
+------------+
| 0xbfd9198c |
+------------+
तो पते पर स्मृति के 4-बाइट ब्लॉक में 0xbfd9198c
हेक्साडेसिमल मान के अनुरूप बिट पैटर्न होता है 0xbfd9198c
। काफी सरल।
इसके बाद, हम तीन मानों का प्रिंट आउट लेते हैं। अन्य उत्तर बताते हैं कि प्रत्येक अभिव्यक्ति का क्या अर्थ है, इसलिए अब संबंध स्पष्ट होना चाहिए।
हम देख सकते हैं कि मूल्य समान हैं, लेकिन केवल बहुत ही निम्न स्तर के अर्थों में ... उनके बिट पैटर्न समान हैं, लेकिन प्रत्येक अभिव्यक्ति के साथ जुड़े प्रकार के डेटा का अर्थ है कि उनके व्याख्या किए गए मान अलग-अलग हैं। उदाहरण के लिए, यदि हम x[0][0][0]
प्रारूप स्ट्रिंग का उपयोग करके प्रिंट करते हैं, तो हमें %d
एक बड़ी नकारात्मक संख्या मिलेगी, इसलिए "मान" व्यवहार में, भिन्न हैं, लेकिन बिट पैटर्न समान है।
यह वास्तव में बहुत सरल है ... आरेखों में, तीर अलग-अलग लोगों के बजाय एक ही स्मृति पते पर इंगित करते हैं। हालाँकि, जब हम अनिर्धारित व्यवहार से अपेक्षित परिणाम के लिए बाध्य करने में सक्षम थे, तो यह सिर्फ - अपरिभाषित है। यह उत्पादन कोड नहीं है, बल्कि पूर्णता के लिए केवल एक प्रदर्शन है।
एक उचित स्थिति में, आप malloc
5 अंतर बिंदुओं की सरणी बनाने के लिए उपयोग करेंगे , और फिर से उस सरणी में इंगित किए गए इन्ट्स बनाने के लिए। malloc
हमेशा एक अद्वितीय पता देता है (जब तक कि आप मेमोरी से बाहर नहीं होते हैं, उस स्थिति में यह NULL या 0 लौटाता है), इसलिए आपको कभी भी इस तरह के सेल्फ-रेफरेंशियल पॉइंटर्स के बारे में चिंता करने की आवश्यकता नहीं होगी।
उम्मीद है कि वह पूरा जवाब है जिसकी आपको तलाश है। आप की उम्मीद करनी चाहिए नहीं x[0]
, x[0][0]
है, और x[0][0][0]
बराबर हो, लेकिन वे अगर मजबूर हो सकता है। यदि आपके सिर पर कुछ भी चला गया है, तो मुझे बताएं ताकि मैं स्पष्ट कर सकूं!
x[0]
,x[0][0]
औरx[0][0][0]
विभिन्न प्रकार हैं। उनकी तुलना नहीं की जा सकती। आपका क्या मतलब है!=
?