2012-02-20 12 views
5

सूचक के लिए किसी को निम्न कोड के उत्पादन में व्याख्या कर सकते हैंसूचक अंकगणित

char* a[] = {"ABC123", "DEF456", "GHI789"}; 
char **p = a; 
cout<<++*p<<std::endl; 
cout<<*p++<<std::endl; 
cout<<++*p<<std::endl; 

आउटपुट:

BC123 
BC123 
EF456 

क्या मेरे लिए भ्रामक है ++ * पी के विभिन्न व्यवहार है और * p ++। मैं उम्मीद कर रहा था होना करने के लिए उत्पादन:

ABC123 
DEF456 
GHI789 
+6

ऑपरेटर पूर्वता। कुछ कोष्ठक जोड़ें और यह स्पष्ट हो जाएगा ... – jrok

उत्तर

3
char* a[] = {"ABC123", "DEF456", "GHI789"}; 
char **p = a; 
cout<<++*p<<std::endl; // 1 
cout<<*p++<<std::endl; // 2 
cout<<++*p<<std::endl; // 3 

लाइन 1 पहले *p पर सरणी "ABC123" में तत्व की ओर इशारा करते हो जाएगा और ++ चाल आगे की ओर एक और इसलिए 'BC123' छपा है।

लाइन 2 *p पर अभी भी BC123 पर इशारा कर रहा है, इसलिए यह मुद्रित है और फिर एक बार मुद्रित ++ किया जाता है। यह संकेतक को

लाइन 3 पर लाइन 1 के समान ही है। आपने p (अब सरणी में दूसरा तत्व) की सामग्री ली है और उस स्ट्रिंग में एक वर्ण को स्थानांतरित किया है, इस प्रकार मुद्रण EF456

(इसके अलावा यहां Pointer arithmetic on string type arrays, how does C++ handle this? पर एक नजर है के रूप में मुझे लगता है कि यह क्या हो रहा है की एक समझ पाने के लिए उपयोगी हो सकता है)

मुद्रित करने के लिए आप क्या उम्मीद काम करेंगे निम्नलिखित:

cout<<*p++<<std::endl; 
cout<<*p++<<std::endl; 
cout<<*p++<<std::endl; 

या

cout<<*p<<std::endl; 
cout<<*(++p)<<std::endl; 
cout<<*(++p)<<std::endl; 

या विभिन्न अन्य तरीकों से (के रूप में अन्य लोगों ने कहा खाता पूर्वता को ध्यान में रखकर)

0

++*p मुद्रण से पहले मार डाला जाता है। तो सूचक वृद्धि, फिर प्रिंट करें। प्रिंटिंग के बाद *p++ निष्पादित किया गया है। प्रिंट करें, फिर वृद्धि करें।

0

बस एक अनुमान है, लेकिन मुझे लगता है कि आप cout<<++*p<<std::endl; का उपयोग करके संदर्भित सूचक को बढ़ा रहे हैं, जो आप वास्तव में कर रहे हैं वह स्ट्रिंग की शुरुआत में चरित्र को बढ़ा रहा है जो पी को इंगित करता है ताकि इसे मानक आउटपुट में आउटपुट किया जा सके।

इसी प्रकार cout<<*p++<<std::endl; आउटपुट के बाद चरित्र को बढ़ा रहा है ताकि अंतिम cout<<++*p<<std::endl; परिणाम दो वृद्धि में हो।

आप ऐसा करें और देखें कि क्या यह काम करता है

cout<<*(++p)<<std::endl; 
cout<<*(p++)<<std::endl; 
cout<<*(++p)<<std::endl; 
+1

उस आउटपुट की आखिरी पंक्ति दुर्भाग्यवश बूम हो जाती है। '++ पी' इसे सरणी – Firedragon

4

शायद यह मदद मिलेगी चाहिए। आप उदाहरण के मोटे तौर पर इस के बराबर है:

++(*p); 
cout << *p << '\n'; 

cout << *p << '\n'; 
++p; 

++(*p); 
cout << *p << '\n'; 

कोष्ठकों के बिना, *p++*(p++) के रूप में पार्स किया गया है के बाद से प्रत्यय वेतन वृद्धि भिन्नता ऑपरेटर की तुलना में अधिक पूर्वता मिल गया है। हालांकि, पूरी अभिव्यक्ति के बाद भी वृद्धि हुई है।

दूसरी ओर, उपसर्ग वृद्धि और * को समान प्राथमिकता मिली है, इसलिए ++*p को ++(*p) के रूप में दाएं से बाएं पार्स किया गया है। यह जानकर कि अभिव्यक्ति से पहले उपसर्ग वृद्धि करना है, अब आप पूरी तस्वीर को एक साथ रख सकते हैं।

+0

के अंत से आगे ले जा रहा है, मुझे यह मिला ... मैं केवल तस्वीर में ऑपरेटर प्राथमिकता ले रहा था, पूरी तरह से सहयोगीता के बारे में भूल रहा था .. धन्यवाद –

1

सी ++ ऑपरेटर प्राथमिकता तालिका के अनुसार, पोस्ट-वृद्धि की प्राथमिकता dereference (*) ऑपरेटर से अधिक है, और पूर्व-वृद्धि और dereference ऑपरेटर की प्राथमिकता है। इसके अलावा पूर्व-वृद्धि और डीरेंसेंस ऑपरेटर दाएं-से-बाएं सहयोगी हैं।

तो पहली पंक्ति में (cout<<++*p<<std::endl;), * और ++ का मूल्यांकन दाएं से बाएं (पहले अव्यवस्था, फिर वृद्धि) से किया जाता है। अब p अभी भी पहली सरणी को इंगित करता है (क्योंकि यह नहीं बदला गया है), लेकिन (* पी) पहली स्ट्रिंग के दूसरे अक्षर को इंगित करता है (आउटपुट इस तथ्य को दिखाता है)।

दूसरी पंक्ति (cout<<*p++<<std::endl;) हालांकि बाद वेतन वृद्धि पहले मूल्यांकन किया जाता है (p के पुराने मूल्य पुन: प्राप्त करने के बाद) और p में वृद्धि की जाती है और अब दूसरी सरणी की ओर इशारा करता है। लेकिन वृद्धि से पहले, पी का मूल्य अभिव्यक्ति में उपयोग किया जाता है और दूसरी पंक्ति के आउटपुट बिल्कुल पहली पंक्ति के रूप में होता है।

तीसरी पंक्ति में, पहले p को संदर्भित किया गया है (दूसरी सरणी के पहले अक्षर को इंगित करें), फिर बढ़ाया गया (दूसरी सरणी के दूसरे अक्षर को इंगित करें), और मान मुद्रित किया गया है।