यह c++ है! सब कुछ संभव है! लेकिन यह c++ है इसलिए इसे समझने के कुछ स्तर की आवश्यकता है। char firstName[4] = { 'J', 'o', 'n', '\0' }
और char lastName[4] = { 'M', 'e', 'e', '\0' }
के एक संभव स्मृति लेआउट यहाँ पर नजर डालते हैं:
+------------+-------+
| Address | Value |
+------------+-------+
| 0x| 0x4A | <- firstName[0] - 'J'
| 0x76543211 | 0x6F | <- firstName[1] - 'o'
| 0x76543212 | 0x6E | <- firstName[2] - 'n'
| 0x76543213 | 0x00 | <- firstName[3] - '\0'
+------------+-------+
| 0x76543214 | 0x4D | <- lastName[0] - 'M'
| 0x76543215 | 0x65 | <- lastName[1] - 'e'
| 0x76543216 | 0x65 | <- lastName[2] - 'e'
| 0x76543217 | 0x00 | <- lastName[3] - '\0'
+------------+-------+
इस स्मृति लेआउट को देखते हुए अगर आप cout << firstName << ' ' << lastName
तुम क्या करने थे
कि अंत करने के लिए 2 1-आयामी सरणियों का एक सरल उदाहरण के साथ शुरू करते हैं 'प्राप्त डी:
0x0x76543214
इन ar किरणें वास्तव में सिर्फ अपने पहले तत्व के लिए एक सूचक हैं! इस सूचक क्षय करने के लिए सरणी जिसे आप यहां के बारे में अधिक पढ़ सकते हैं दिखाता है: http://en.cppreference.com/w/cpp/language/array#Array-to-pointer_decay
इससे पहले कि हम ले जाने के कुछ यहाँ याद रखना आवश्यक है है पर, char
रों इसलिए सरणी में प्रत्येक अनुवर्ती char
का पता ठीक वैसे ही 1-बाइट तक का समय लग जाएगा बस अगला पता हो। Subscript Operator द्वारा इस तरह से लीवरेज किया गया है: firstName[1]
*(firstName + 1)
के बराबर है। यह char
एस के लिए सच है लेकिन यह किसी अन्य प्रकार के लिए भी सच है जो 1-बाइट से अधिक लेता है। के उदाहरण के लिए लेते हैं:
+------------+--------+
| Address | Value |
+------------+--------+
| 0x76543218 | 0x0001 | <- siArray[0] - 1
| 0x7654321A | 0x0002 | <- siArray[1] - 2
| 0x7654321C | 0x0003 | <- siArray[2] - 3
| 0x7654321E | 0x0004 | <- siArray[3] - 4
+------------+--------+
हालांकि cout << siArray << ' ' << &(siArray[1])
इच्छा उत्पादन:
0x76543218 0x7654321A
*(siArray + 1)
अब भी एक ही होगा short siArray = { 1, 2, 3, 4 }
, siArray
के संभावित स्मृति लेआउट कैसा लगेगा siArray
का तत्व siArray[1]
के रूप में। ऐसा इसलिए है क्योंकि पॉइंटर अंकगणित c++ पर हस्ताक्षर किए जाने वाले पते के प्रकार पर विचार किया जाता है, इस प्रकार short*
में वृद्धि करने से वास्तव में sizeof(short)
द्वारा पता बढ़ जाएगा। आप पॉइंटर अंकगणितीय के बारे में अधिक पढ़ सकते हैं: http://en.cppreference.com/w/cpp/language/operator_arithmetic
आखिरकार देखते हैं कि कैसे c++ स्टोर 2-आयामी सरणी। यह देखते हुए: char name[2][4] = { { 'J', 'o', 'n', '\0' }, { 'M', 'e', 'e', '\0' } }
एक संभव स्मृति लेआउट होगा:
+------------+-------+
| Address | Value |
+------------+-------+
| 0x76543220 | 0x4A | <- name[0][0] - 'J'
| 0x76543221 | 0x6F | <- name[0][1] - 'o'
| 0x76543222 | 0x6E | <- name[0][2] - 'n'
| 0x76543223 | 0x00 | <- name[0][3] - '\0'
| 0x76543224 | 0x4D | <- name[1][0] - 'M'
| 0x76543225 | 0x65 | <- name[1][1] - 'e'
| 0x76543226 | 0x65 | <- name[1][2] - 'e'
| 0x76543227 | 0x00 | <- name[1][3] - '\0'
+------------+-------+
के बाद से हम जानते हैं कि एक 1-आयामी सरणी मान वास्तव में सिर्फ एक सूचक है, हम इस स्मृति लेआउट से देख सकते हैं कि name[0]
एक सूचक नहीं है, यह सिर्फ है पहली सरणी का पहला अक्षर। इस प्रकार name
में 2 1-आयामी सरणी पॉइंटर्स नहीं हैं, लेकिन इसमें 2 सरणी की सामग्री शामिल है। (आकस्मिक रूप से 32-बिट मशीन पर पॉइंटर्स को संग्रहीत नहीं किया जाता है, जो 8-बाइट मेमोरी बचाता है, जो 8-बाइट 2-आयामी सरणी के लिए काफी महत्वपूर्ण है।) name
को char**
के रूप में इलाज करने का प्रयास करने वाले वर्णों को एक सूचक।
इस समझ में आ करने के बाद हम वास्तव में सिर्फ c++ के सूचक अंकगणित का उपयोग कर मूल्य भिन्नता को खोजने के लिए बचने की जरूरत है।
const short si2DArray[2][3] = { { 11, 12, 13 }, { 21, 22, 23 } };
const auto psi2DPointer = reinterpret_cast<const char*>(si2DArray);
for(auto i = 0U; i < size(si2DArray); ++i) {
for(auto j = 0U; j < size(*si2DArray); ++j) {
cout << *reinterpret_cast<const short*>(psi2DPointer + i * sizeof(*si2DArray) + j * sizeof(**si2DArray)) << '\t';
}
cout << endl;
}
Live Example
ध्यान दें कि यह उदाहरण भले ही मैंने संदर्भ में si2DArray
सोचा psi2DPointer
: है कि हम इतना है कि जोड़ने 1 वास्तव में सिर्फ उदाहरण के लिए 1. जोड़ रहा है तो एक char*
के साथ काम करने की आवश्यकता होगी ऐसा करने के लिए मैं अभी भी si2DArray
से जानकारी का उपयोग कर रहा अनुक्रमण करने के लिए, अर्थात्:
- कितने सरणियों प्रमुख आयाम में कर रहे हैं:
size(si2DArray)
,210
- कितने तत्वों नाबालिग आयाम में कर रहे हैं:
size(*si2DArray)
- क्या नाबालिग आयाम की स्मृति में आकार है:
sizeof(**si2DArray)
आप इस प्रकार देख सकते हैं: sizeof(*si2DArray)
क्या सरणी के तत्व प्रकार है कि एक सरणी से एक सूचक में कनवर्ट करने से जानकारी का नुकसान पर्याप्त है। आप तत्व प्रकार को संरक्षित करने के लिए लुभाने वाले हो सकते हैं, जिससे पॉइंटर अंकगणित को सरल बना दिया जा सके। यह नोट करना reinterpret_cast
से है कि केवल char*
में रूपांतरण परिभाषित व्यवहार माना जाता है फ़ायदेमंद हो सकता है: http://en.cppreference.com/w/cpp/language/reinterpret_cast#Type_aliasing
[प्रासंगिक पूछे जाने वाले प्रश्न] (http://stackoverflow.com/questions/4810664/) – fredoverflow