यह मुहावरा स्वाभाविक रूप से 1D सरणी आवंटन से बाहर आता है। चलो कुछ मनमाने प्रकार के 1D सरणी आवंटित करने के साथ शुरू करते हैं T
:
T *p = malloc( sizeof *p * N );
सरल, सही? अभिव्यक्ति *p
प्रकार है T
तो, sizeof *p
के रूप में ही परिणाम देता है sizeof (T)
, तो हम एक के लिए पर्याप्त जगह का आवंटन कर रहे हैं N
के तत्व सरणी T
। यह किसी भी प्रकार केT
लिए सही है ।
अब, T
एक सरणी प्रकार के साथ स्थानापन्न करते हैं R [10]
। तब हमारा आवंटन हो जाता है
R (*p)[10] = malloc( sizeof *p * N);
यहां अर्थ विज्ञान हैं ठीक उसी -1 डी आवंटन पद्धति के रूप में; यह सब बदल दिया गया प्रकार है p
। इसके बजाय T *
, यह अब है R (*)[10]
। अभिव्यक्ति *p
का प्रकार है T
जो टाइप है R [10]
, इसलिए sizeof *p
इसके बराबर है sizeof (T)
जो इसके बराबर है sizeof (R [10])
। इसलिए हम एक के लिए पर्याप्त जगह का आवंटन कर रहे हैं N
द्वारा 10
की तत्व सरणी R
।
हम चाहे तो इसे और भी आगे ले जा सकते हैं; मान लीजिए कि R
एक सरणी प्रकार है int [5]
। इसके लिए R
और हमें मिलता है
int (*p)[10][5] = malloc( sizeof *p * N);
एक ही सौदा - sizeof *p
रूप में ही है sizeof (int [10][5])
, और हम स्मृति बड़ा पर्याप्त का एक सन्निहित हिस्सा आवंटन एक धारण करने के लिए हवा N
से 10
द्वारा 5
की सरणी int
।
तो वह आवंटन पक्ष है; पहुंच पक्ष के बारे में क्या?
याद रखें कि []
सबस्क्रिप्ट ऑपरेशन सूचक अंकगणित के संदर्भ में परिभाषित किया गया है: 1 केa[i]
रूप में परिभाषित किया गया है । इस प्रकार, सबस्क्रिप्ट ऑपरेटर को स्पष्ट रूप से एक पॉइंटर संदर्भित करता है। यदि कोई पॉइंटर है , तो आप इंगित किए गए मान तक पहुँच सकते हैं या तो स्पष्ट रूप से एकतरफा ऑपरेटर के साथ डीरेफरेंसिंग द्वारा :*(a + i)
[]
p
T
*
T x = *p;
या[]
सबस्क्रिप्ट ऑपरेटर का उपयोग करके :
T x = p[0]; // identical to *p
इस प्रकार, यदि p
किसी सरणी के पहले तत्व को इंगित करता है , तो आप पॉइंटर पर एक सबस्क्रिप्ट का उपयोग करके उस सरणी के किसी भी तत्व तक पहुंच सकते हैं p
:
T arr[N];
T *p = arr; // expression arr "decays" from type T [N] to T *
...
T x = p[i]; // access the i'th element of arr through pointer p
अब, हमारा प्रतिस्थापन ऑपरेशन फिर से करें और T
सरणी प्रकार के साथ बदलें R [10]
:
R arr[N][10];
R (*p)[10] = arr; // expression arr "decays" from type R [N][10] to R (*)[10]
...
R x = (*p)[i];
एक तुरंत स्पष्ट अंतर; हम p
सबस्क्रिप्ट ऑपरेटर को लागू करने से पहले स्पष्ट रूप से dereferencing हैं । हम इसमें सब्स्क्राइब नहीं करना चाहते हैं p
, हम किस p
बिंदु पर (इस मामले में, ऐरे arr[0]
) में सबस्क्रिप्ट करना चाहते हैं । चूंकि यूनिफ़ॉर्म *
में सबस्क्रिप्ट []
ऑपरेटर की तुलना में कम वरीयता होती है , इसलिए हमें स्पष्ट रूप से समूह में कोष्ठक का उपयोग p
करना होगा *
। लेकिन ऊपर से याद है कि के *p
रूप में ही है p[0]
, तो हम उस के साथ स्थानापन्न कर सकते हैं
R x = (p[0])[i];
या केवल
R x = p[0][i];
इस प्रकार, यदि p
2 डी सरणी की ओर इशारा करते हैं, तो हम इस p
तरह से उस सरणी में अनुक्रमित कर सकते हैं :
R x = p[i][j]; // access the i'th element of arr through pointer p;
// each arr[i] is a 10-element array of R
इसे उसी निष्कर्ष पर ले जाना जैसा ऊपर और प्रतिस्थापन के R
साथ है int [5]
:
int arr[N][10][5];
int (*p)[10][5]; // expression arr "decays" from type int [N][5][10] to int (*)[10][5]
...
int x = p[i][j][k];
यह केवल एक ही काम करता है अगर p
एक नियमित सरणी की ओर इशारा करता है, या अगर यह स्मृति के माध्यम से आवंटित करता है malloc
।
इस मुहावरे के निम्नलिखित लाभ हैं:
- यह आसान है - कोड की केवल एक पंक्ति, जैसा कि टुकड़े टुकड़े आवंटन विधि के विपरीत है
T **arr = malloc( sizeof *arr * N );
if ( arr )
{
for ( size_t i = 0; i < N; i++ )
{
arr[i] = malloc( sizeof *arr[i] * M );
}
}
- आवंटित सरणी की सभी पंक्तियाँ * सन्निहित * हैं, जो ऊपर दिए गए टुकड़े-टुकड़े आवंटन विधि के मामले में नहीं है;
- एक कॉल के साथ सरणी को डीलक्लोकेटिंग करना उतना ही आसान है
free
। फिर से, टुकड़े टुकड़े आवंटन विधि के साथ सच नहीं है, जहां आपको डील करने arr[i]
से पहले प्रत्येक को निपटाना होगा arr
।
कभी-कभी टुकड़ों की आवंटन विधि बेहतर होती है, जैसे कि जब आपका हीप बुरी तरह से खंडित हो जाता है और आप अपनी याददाश्त को एक सन्निहित अंग के रूप में आवंटित नहीं कर सकते हैं, या आप एक "दांतेदार" सरणी आवंटित करना चाहते हैं जहां प्रत्येक पंक्ति की एक अलग लंबाई हो सकती है। लेकिन सामान्य तौर पर, यह जाने का बेहतर तरीका है।
1. याद रखें कि सरणियाँ संकेत नहीं हैं - इसके बजाय, सरणी अभिव्यक्तियाँ आवश्यक रूप से सूचक अभिव्यक्तियों में बदल जाती हैं।