दिलचस्प पोस्ट
सी ++ में पीओडी प्रकार क्या हैं? पॉइंटर्स का उपयोग कर स्ट्रिंग को संशोधित करते समय सेगमेंटेशन गलती होती है? काम करने के लिए कार्यवाही में खोजदृश्य नहीं मिल सकता है ईवेंट हैंडलर में रिक्त जांच का उपयोग पृष्ठ स्क्रॉल किए जाने के बाद jQuery के ड्रैगएबल गलत जगह में सहायक दिखाता है सेगमेंट पेड़, अंतराल के पेड़, बाइनरी अनुक्रमित पेड़ और रेंज पेड़ों के बीच अंतर क्या हैं? SQL सर्वर में datetime में varchar कनवर्ट करें यदि मैं इसे स्पष्ट रूप से नहीं करता, तो सी ++ क्लास सदस्यों को कैसे आरंभ किया जाता है? अपवाद बनाम निषेध इंटरफेस के लिए कार्यक्रम का क्या मतलब है? कोर डेटा में सभी प्रविष्टियों को हटाएं / रीसेट करें? कैसे कोणीय यहाँ क्षेत्र के साथ अद्यतन नहीं करता है? IllegalStateException: इस कार्रवाई को ViewPager के साथ सेवइन्स्टेंसस्टेट के बाद नहीं कर सकता प्रोजेक्ट में कोई डिफ़ॉल्ट नहीं है। प्रॉपर्टी फाइल! एक सेट करने के लिए प्रोजेक्ट गुण संपादित करें सी # का प्रयोग कर एंटीवायरस को विंडोज़ पर खोजें

सूचक-टू-पॉइंटर के लिए 2 डी सरणी का रूपांतरण

Activity solution[a][b]; ... Activity **mother = solution; 

मैं ऑब्जेक्ट के 2 डी सरणी को पॉइंटर-टू-पॉइंटर में परिवर्तित करना चाहता हूं। मैं यह कैसे कर सकता हूँ;

मैंने इसे Google पर खोजा हालांकि मुझे केवल एक आयाम सरणी उदाहरण मिला।

वेब के समाधान से एकत्रित समाधान "सूचक-टू-पॉइंटर के लिए 2 डी सरणी का रूपांतरण"

एक मात्र रूपांतरण आपकी मदद नहीं करेगा 2 डी सरणी प्रकार और सूचक-टू-पॉइंटर प्रकार के बीच किसी भी प्रकार की कोई संगतता नहीं है। इस तरह के रूपांतरण कोई मतलब नहीं होगा

अगर आपको वाकई वास्तव में ऐसा करने की ज़रूरत है, तो आपको एक अतिरिक्त मध्यवर्ती "पंक्ति अनुक्रमणिका" सरणी शुरू करनी होगी, जो 2 डी सर सिमेंटिक्स और पॉइंटर-टू-पॉइंटर सिमेंटिक्स

 Activity solution[a][b]; Activity *solution_rows[a] = { solution[0], solution[1] /* and so on */ }; Activity **mother = solution_rows; 

अब mother[i][j] आपको solution[i][j] तक पहुंच प्रदान करेगा।

कारण यह आप एक-आयामी arrays के लिए कर सकते हैं और दो-आयामी arrays के लिए नहीं है जिस तरह से वास्तविक सरणी तत्व स्मृति में संग्रहीत हैं। एक-आयामी arrays के लिए, सभी तत्वों को लगातार संग्रहित किया जाता है, इसलिए अभिव्यक्ति array[i] अभिव्यक्ति *(array + i) बराबर है। जैसा कि आप देख सकते हैं, सरणी का आकार किसी सरणी अनुक्रमणिका संचालन को करने के लिए आवश्यक नहीं है। हालांकि, दो-आयामी arrays के लिए, तत्व "पंक्ति प्रमुख" क्रम में संग्रहीत किए जाते हैं, जिसका अर्थ है कि शून्य पंक्ति में सभी तत्व पहले संग्रहीत किए जाते हैं, पहली पंक्ति में तत्वों के बाद, दूसरी पंक्ति में तत्वों के बाद , आदि। इसलिए, अभिव्यक्ति array[i][j] *(array + (i * ROW_SIZE) + j) बराबर है *(array + (i * ROW_SIZE) + j) , जहां ROW_SIZE प्रत्येक पंक्ति में तत्वों की संख्या है। इसलिए, सरणी के आकार के आकार को एक सरणी सूचकांक संचालन करने के लिए आवश्यक है, और सूचक पॉइंट में एआरए चर कास्टिंग करता है, उस जानकारी को खो देता है

मैं ऑब्जेक्ट के 2 डी सरणी को पॉइंटर-टू-पॉइंटर में परिवर्तित करना चाहता हूं। मैं यह कैसे कर सकता हूँ?

क्यूं कर? क्या ऐसा इसलिए है क्योंकि एक इंटरफेस पॉइंटर को संकेतक की अपेक्षा करता है?

यदि हां, तो आपको एक नया सरणी बनाने की आवश्यकता होगी जिसमें उन पॉइंटर्स शामिल होंगे

 Activity solution[a][b]; Activity* solutionPtrs[a]; for (int i = 0; i < a; ++i) solutionPtrs[a] = solution[a]; Activity** mother = solutionPtrs; 

आप बस T के T 2 डी सरणी को क्यों नहीं डाल सकते? ठीक है, क्योंकि उनके पास एक-दूसरे के साथ कुछ नहीं करना है!

आप T[a] को T* डाल सकते हैं क्योंकि आपको सरणी के पहले तत्व के लिए एक सूचक मिलता है।

आप इसे 2 डी सरणियों के साथ भी कर सकते हैं, लेकिन अगर आपके पास T[a][b] तो यह एक (T[b])* को घटा देता है क्योंकि 2 डी एरे पॉइंटर्स की एक सरणी नहीं है, यह सरणी की एक सरणी है ।

यह सी ++ है ! सब कुछ संभव है! लेकिन यह सी ++ है इसलिए इसे समझने के कुछ स्तर की आवश्यकता होती है।

अंत में, 2 1-आयामी arrays का एक सरल उदाहरण के साथ शुरू करते हैं: char firstName[4] = { 'J', 'o', 'n', '\0' } और char lastName[4] = { 'M', 'e', 'e', '\0' } यहाँ एक संभव स्मृति लेआउट को देखें:

 +------------+-------+ | Address | Value | +------------+-------+ | 0x76543210 | 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 करना था cout << firstName << ' ' << lastName आपको मिलना चाहिए:

0x76543210 0x76543214

ये सरणी वास्तव में केवल अपने पहले तत्व के लिए एक संकेतक हैं! यह सरणी को पॉइंटर क्षय को दर्शाता है, जिसे आप यहां यहां और भी पढ़ सकते हैं: http://en.cppreference.com/w/cpp/language/array#Array-to-pointer_decay

ध्यान देने के लिए यहां कुछ महत्वपूर्ण बातों पर ध्यान देने से पहले, char 1-बाइट में लेना है, ताकि प्रत्येक अगले char का पता सरणी में होगा और यह अगले पता होगा। इस प्रकार सबस्क्रिप्ट ऑपरेटर द्वारा इस तरह से लीवरेज किया गया है: firstName[1] *(firstName + 1) बराबर है। यह char लिए सही है लेकिन यह किसी अन्य प्रकार के लिए भी सही है जो 1-बाइट से अधिक लेता है। चलो उदाहरण के लिए लेते हैं: short siArray = { 1, 2, 3, 4 } , siArray का संभावित स्मृति लेआउट ऐसा दिखेगा:

 +------------+--------+ | 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 0x7654321 ए

*(siArray + 1) अभी भी siArray का एक ही तत्व siArray[1] रूप में siArray[1] इसका कारण यह है कि सूचक अंकगणितीय सी ++ करते समय पते के प्रकार पर विचार किया जाता है, इस प्रकार short* होकर short* वास्तव में sizeof(short) द्वारा पता बढ़ जाएगा आप पॉइंटर अंकगणित के बारे में यहां अधिक पढ़ सकते हैं: http://en.cppreference.com/w/cpp/language/operator_arithmetic

अंत में देखते हैं कि कैसे सी ++ भंडार 2-आयामी arrays दिए गए: 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 रूप में name का इलाज करने की कोशिश कर रहा char** अक्षरों का उपयोग करने की कोशिश करेगा एक सूचक के रूप में


यह समझने के बाद हम वास्तव में भ्रम के मूल्य को खोजने के लिए सी ++ के पॉइंटर अंकगणितीय का उपयोग करने से बचने की आवश्यकता है। ऐसा करने के लिए हमें एक char* साथ काम करने की आवश्यकता होगी ताकि 1 जोड़ने से वास्तव में 1 जोड़ना होगा। उदाहरण के लिए:

 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; } 

लाइव उदाहरण

ध्यान दें कि इस उदाहरण में हालांकि मैं संदर्भित करता si2DArray कि psi2DPointer ने सोचा था psi2DPointer मैं अभी भी si2DArray से जानकारी का उपयोग कर रहा हूं, अर्थात्:

  1. प्रमुख आयाम में कितने size(si2DArray) : size(si2DArray)
  2. कितने तत्व छोटे आयाम में हैं: size(*si2DArray)
  3. मामूली आयाम की स्मृति में आकार क्या है: sizeof(*si2DArray)
  4. सरणी का तत्व प्रकार क्या है: sizeof(**si2DArray)

आप इस तरह देख सकते हैं कि सरणी से एक संकेतक को परिवर्तित करने से जानकारी की हानि पर्याप्त है आप तत्व प्रकार को संरक्षित करने के लिए परीक्षा ले सकते हैं, जिससे पॉइंटर अंकगणितीय को सरल भी किया जा सकता है। यह ध्यान देने योग्य है कि केवल char* रूपांतरणों को reinterpret_cast : reinterpret_cast करके परिभाषित व्यवहार माना जाता है: http://en.cppreference.com/w/cpp/language/reinterpret_cast#Type_aliasing

आप नहीं कर सकते वे मूल रूप से विभिन्न प्रकार के होते हैं

सुनिश्चित नहीं हैं कि आप इस तरह से कुछ की तलाश कर रहे थे। आपको क्या हासिल करना है, इसके बारे में अधिक जानकारी प्रदान करनी चाहिए। वे मूल रूप से विभिन्न प्रकार के होते हैं एक समाधान नीचे है

रिकॉर्ड के लिए, अगर कोई इसे उपयोगी पाता है:

 // define matrix double A[3][3] = { { 1, 2, 3}, { 4, 5, 6}, { 7, 8, 9} }; // allocate memory double ** A_ptr = (double **) malloc(sizeof (double *) * 3); for (int i = 0; i < 3; i++) A_ptr[i] = (double *) malloc(sizeof (double) * 3); // copy matrix for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { A_ptr[i][j] = A[i][j]; printf(" %f ", A_ptr[i][j]); } }