किसी सरणी में अनुक्रमण C के साथ शून्य से शुरू होता है और 1 से नहीं?
किसी सरणी में अनुक्रमण C के साथ शून्य से शुरू होता है और 1 से नहीं?
जवाबों:
सी में, एक सरणी का नाम अनिवार्य रूप से एक संकेतक है [लेकिन टिप्पणियों को देखें] , एक स्मृति स्थान का एक संदर्भ, और इसलिए अभिव्यक्ति प्रारंभिक तत्व से दूर array[n]
एक स्मृति स्थान n
तत्वों को संदर्भित करता है । इसका मतलब है कि इंडेक्स का उपयोग ऑफसेट के रूप में किया जाता है। सरणी का पहला तत्व स्मृति स्थान में बिल्कुल समाहित है जो सरणी संदर्भित करता है (0 तत्व दूर), इसलिए इसे इस रूप में निरूपित किया जाना चाहिए array[0]
।
अधिक जानकारी के लिए:
http://developeronline.blogspot.com/2008/04/why-array-index-should-start-from-0.html
sizeof arr
सरणी ऑब्जेक्ट का आकार देता है, न कि पॉइंटर का आकार।
sizeof
ऑपरेटर के संचालन को छोड़कर , या यूनिरी &
ऑपरेटर है, या एक सरणी को आरम्भ करने के लिए उपयोग किया जाने वाला एक स्ट्रिंग शाब्दिक है, एक अभिव्यक्ति जो टाइप की है" सरणी प्रकार "को" ऑब्जेक्ट के लिए पॉइंटर से टाइप "के साथ एक अभिव्यक्ति में बदल दिया जाता है जो सरणी ऑब्जेक्ट के प्रारंभिक तत्व को इंगित करता है और एक अंतराल नहीं है। यदि सरणी ऑब्जेक्ट में स्टोरेज क्लास पंजीकृत है, तो व्यवहार अपरिभाषित है। "
यह सवाल एक साल पहले पोस्ट किया गया था, लेकिन यहाँ जाता है ...
जबकि दिज्क्स्ट्रा का लेख (पहले-हटाए गए उत्तर में संदर्भित ) गणितीय दृष्टिकोण से समझ में आता है, यह प्रोग्रामिंग के लिए उतना प्रासंगिक नहीं है।
भाषा विनिर्देश और संकलक-डिजाइनरों द्वारा लिया गया निर्णय कंप्यूटर सिस्टम-डिजाइनरों द्वारा 0 पर गणना शुरू करने के लिए किए गए निर्णय पर आधारित है।
से हवाला देते हुए शांति के लिए एक दलील डैनी कोहेन द्वारा।
किसी भी आधार b के लिए, पहला b ^ N गैर-नकारात्मक पूर्णांक केवल N अंक (अग्रणी शून्य सहित) द्वारा दर्शाया जाता है, यदि नंबर 0 पर शुरू होता है।
इसे काफी आसानी से परखा जा सकता है। आधार -2 में, 2^3 = 8
8 वां नंबर है:
111
3
बिट्स का उपयोग करके प्रतिनिधित्व किया जा सकता है , जबकि 1000
एक अतिरिक्त बिट (4 बिट्स) की आवश्यकता होगी।
कंप्यूटर मेमोरी एड्रेस में बिट्स 2^N
द्वारा संबोधित सेल होते हैं N
। अब अगर हम 1 पर गिनना शुरू करते हैं, तो 2^N
कोशिकाओं को N+1
पता लाइनों की आवश्यकता होगी । ठीक 1 पते तक पहुंचने के लिए अतिरिक्त-बिट की आवश्यकता होती है। ( 1000
उपरोक्त मामले में।) इसे हल करने का एक और तरीका यह होगा कि अंतिम पते को दुर्गम छोड़ दें, और N
पता लाइनों का उपयोग करें ।
दोनों 0 से गिनती शुरू करने की तुलना में उप-इष्टतम समाधान हैं , जो बिल्कुल N
पते की पंक्तियों का उपयोग करके सभी पते को सुलभ रखेंगे !
गणना शुरू करने का निर्णय 0
, तब से सभी डिजिटल सिस्टमों को अनुमति दे चुका है , जिसमें उन पर चल रहे सॉफ्टवेयर भी शामिल हैं, क्योंकि यह कोड के लिए अनुवाद करने के लिए सरल बनाता है कि अंतर्निहित सिस्टम क्या व्याख्या कर सकता है। यदि ऐसा नहीं होता, तो मशीन और प्रोग्रामर के बीच, हर ऐरे एक्सेस के लिए एक अनावश्यक अनुवाद ऑपरेशन होता। यह संकलन को आसान बनाता है।
कागज से उद्धरण:
a[b]
लागू किया गया था *(a+b)
। आज भी आप 2[a]
इसके बजाय लिख सकते हैं a[2]
। अब यदि अनुक्रमणिका 0 पर शुरू नहीं हुई है तो a[b]
चालू हो जाएगी *(a+b-1)
। यह 0 के बजाय समय के CPU पर 2 अतिरिक्त की आवश्यकता होगी, जिसका अर्थ है आधी गति। स्पष्ट रूप से वांछनीय नहीं।
क्योंकि 0 सूचक से सरणी के प्रमुख से सरणी के पहले तत्व तक कितनी दूर है।
विचार करें:
int foo[5] = {1,2,3,4,5};
0 का उपयोग करने के लिए हम करते हैं:
foo[0]
लेकिन फू एक पॉइंटर को विघटित करता है, और उपरोक्त एक्सेस के पास इसे एक्सेस करने का एनालॉग पॉइंटर अंकगणितीय तरीका है
*(foo + 0)
इन दिनों सूचक अंकगणितीय का उपयोग अक्सर नहीं किया जाता है। हालांकि, जब वापस लौटा, तो उस शुरुआती बिंदु से एक पता लेने और X "ints" को स्थानांतरित करने का यह एक सुविधाजनक तरीका था। बेशक अगर आप बस वहीं रहना चाहते हैं जहां आप हैं, तो आप सिर्फ 0 जोड़ें!
क्योंकि 0-आधारित सूचकांक अनुमति देता है ...
array[index]
... के रूप में लागू किया जा ...
*(array + index)
यदि सूचकांक 1-आधारित था, तो संकलक को उत्पन्न करने की आवश्यकता होगी: *(array + index - 1)
और यह "-1" प्रदर्शन को चोट पहुंचाएगा।
क्योंकि इसने संकलक और लिंकर को सरल (लिखने में आसान) बना दिया।
संदर्भ :
"... एक पते और एक ऑफसेट द्वारा संदर्भित मेमोरी को लगभग सभी कंप्यूटर आर्किटेक्चर पर सीधे हार्डवेयर में दर्शाया जाता है, इसलिए सी में यह डिज़ाइन विवरण संकलन को आसान बनाता है"
तथा
"... यह एक सरल कार्यान्वयन के लिए बनाता है ..."
सरणी सूचकांक हमेशा शून्य से शुरू होता है। मान लें कि आधार का पता 2000 है। अब arr[i] = *(arr+i)
। अब if i= 0
, इसका मतलब *(2000+0
) सरणी में पहले तत्व के आधार पते या पते के बराबर है। इस इंडेक्स को ऑफ़सेट के रूप में माना जाता है, इसलिए बायडेफ़ॉल्ट इंडेक्स शून्य से शुरू होता है।
इसी कारण से, जब यह बुधवार है और कोई आपसे पूछता है कि बुधवार को कितने दिन टिकते हैं, तो आप 1 के बजाय 0 कहते हैं, और जब यह बुधवार होता है और कोई आपसे पूछता है कि गुरुवार तक कितने दिन हैं, तो आप कहते हैं कि 2 के बजाय 1 है।
शून्य-आधारित नंबरिंग के लिए मैंने जो सबसे सुरुचिपूर्ण विवरण पढ़ा है, वह एक अवलोकन है कि मान संख्या रेखा पर चिह्नित स्थानों पर संग्रहीत नहीं किए जाते हैं, बल्कि उनके बीच के रिक्त स्थान में हैं। पहला आइटम शून्य और एक के बीच संग्रहीत किया जाता है, अगले एक और दो के बीच, आदि। Nth आइटम N-1 और N के बीच संग्रहीत किया जाता है। दोनों तरफ संख्याओं का उपयोग करके आइटम की एक श्रेणी का वर्णन किया जा सकता है। नीचे दिए गए नंबरों का उपयोग करके वर्णित किए गए सम्मेलन द्वारा व्यक्तिगत आइटम हैं। यदि किसी को एक सीमा (X, Y) दी जाती है, तो नीचे दी गई संख्या का उपयोग करके अलग-अलग संख्याओं की पहचान करने का अर्थ है कि कोई भी अंकगणित (यह आइटम X) का उपयोग किए बिना पहले आइटम की पहचान कर सकता है, लेकिन अंतिम आइटम (Y) की पहचान करने के लिए किसी को Y से घटा देना चाहिए -1)। उपरोक्त संख्या का उपयोग करके आइटम की पहचान करना एक सीमा में अंतिम आइटम की पहचान करना आसान होगा (यह आइटम वाई होगा)।
हालाँकि, यह उनके ऊपर की संख्या के आधार पर वस्तुओं की पहचान करने के लिए भयानक नहीं होगा, सीमा में पहली वस्तु (एक्स, वाई) को परिभाषित करते हुए एक्स के ऊपर एक होने के नाते आम तौर पर इसे नीचे (एक्स +) के रूप में परिभाषित करने की तुलना में अधिक अच्छी तरह से बाहर काम करता है 1)।
एक्स-वाई का उपयोग करके एक पिक्सेल स्क्रीन तक पहुंचने का प्रयास करें, 1-आधारित मैट्रिक्स पर वाई समन्वय करता है। सूत्र बिलकुल जटिल है। जटिल क्यों है? क्योंकि आप अंत में X, Y कोर्ड्स को एक नंबर, ऑफ़सेट में परिवर्तित करते हैं। आपको X, Y को ऑफ़सेट में बदलने की आवश्यकता क्यों है? क्योंकि यह है कि मेमोरी को कंप्यूटर के अंदर कैसे व्यवस्थित किया जाता है, मेमोरी सेल्स (सरणियों) की एक सतत स्ट्रीम के रूप में। कंप्यूटर सरणी कोशिकाओं से कैसे निपटता है? ऑफसेट (पहली सेल से विस्थापन, एक शून्य-आधारित अनुक्रमण मॉडल) का उपयोग करना।
इसलिए कोड में कुछ बिंदु पर आपको 1-आधार सूत्र को 0-आधारित सूत्र में परिवर्तित करने के लिए (या संकलक की आवश्यकता) की आवश्यकता होती है क्योंकि कंप्यूटर स्मृति के साथ कैसे व्यवहार करता है।
मान लें कि हम आकार 5
इंट सरणी बनाना चाहते हैं [5] = [2,3,5,9,8]
सरणी के 1 तत्व को स्थान 100 पर बताया गया है
और हमें लगता है कि अनुक्रमण 1 से शुरू होता है न कि 1 से 0.
अब हमें अनुक्रमणिका की सहायता से
1 तत्व का स्थान ज्ञात करना है (याद रखें कि 1 तत्व का स्थान 100 है)
चूंकि पूर्णांक का आकार 4-बिट है
इसलिए -> अनुक्रमणिका 1 की स्थिति का
आकार होगा सूचकांक (1) * पूर्णांक का आकार (4) = 4
इसलिए वास्तविक स्थिति यह हमें दिखाएगी कि
100 + 4 = 104 है
जो सत्य नहीं है क्योंकि प्रारंभिक स्थान 100 पर था।
यह 104 पर 100 नहीं की ओर इशारा किया जाना चाहिए यह
गलत है
अब मान लें कि हमने अनुक्रमण को 0 से लिया है
तो
1 तत्व की स्थिति
सूचकांक (0) के आकार का होना चाहिए * पूर्णांक का आकार (४) = ०
इसलिए ->
१ तत्व का स्थान १०० + ० = १०० है
और यही तत्व का वास्तविक स्थान था
यही कारण है कि अनुक्रमण ० से शुरू होता है;
मुझे उम्मीद है कि इससे आपकी बात साफ हो जाएगी।
मैं जावा बैकग्राउंड से हूं। मैंने इस प्रश्न का उत्तर आरेख में प्रस्तुत किया है जिसके नीचे मैंने एक कागज़ के टुकड़े में लिखा है जो स्व व्याख्यात्मक है
मुख्य चरण:
नोट : छवि में दिखाए गए ब्लॉक मेमोरी प्रतिनिधित्व है
सबसे पहले आपको यह जानना होगा कि सरणियों को आंतरिक रूप से संकेत के रूप में माना जाता है क्योंकि "सरणी के नाम में ही सरणी के पहले तत्व का पता होता है"
ex. int arr[2] = {5,4};
विचार करें कि सरणी 100 पते पर शुरू होती है इसलिए तत्व पहला तत्व पता 100 पर होगा और दूसरा अब 104 पर होगा, इस पर विचार करें कि यदि सरणी सूचकांक 1 से शुरू होता है, तो
arr[1]:-
यह इस तरह संकेत बिंदुओं में लिखा जा सकता है-
arr[1] = *(arr + 1 * (size of single element of array));
int के आकार पर विचार करें 4bytes, अब,
arr[1] = *(arr + 1 * (4) );
arr[1] = *(arr + 4);
जैसा कि हम जानते हैं कि सरणी नाम में इसके पहले तत्व का पता है, इसलिए अब गिरफ्तार किया गया है = 100,
arr[1] = *(100 + 4);
arr[1] = *(104);
जो देता है,
arr[1] = 4;
इस अभिव्यक्ति के कारण हम पता 100 पर तत्व तक पहुंचने में असमर्थ हैं जो आधिकारिक पहला तत्व है,
अब विचार करें कि ऐरे इंडेक्स 0 से शुरू होता है, इसलिए
arr[0]:-
इसे हल किया जाएगा
arr[0] = *(arr + 0 + (size of type of array));
arr[0] = *(arr + 0 * 4);
arr[0] = *(arr + 0);
arr[0] = *(arr);
अब, हम जानते हैं कि सरणी नाम में इसके पहले तत्व का पता है,
arr[0] = *(100);
जो सही परिणाम देता है
arr[0] = 5;
इसलिए सरणी सूचकांक हमेशा 0 से c में शुरू होता है।
संदर्भ: सभी विवरण पुस्तक "सी प्रोग्रामिंग लैंग्वेज बाय ब्रायन कर्निंगन और डेनिस रिची" में लिखे गए हैं
सरणी में, सूचकांक प्रारंभिक तत्व से दूरी बताता है। तो, पहला तत्व शुरुआती तत्व से 0 की दूरी पर है। तो, इसीलिए सरणी 0 से शुरू होती है।
यह क्योंकि सरणी में address
दाईं ओर इंगित करना है element
। आइए नीचे दिए गए एरे को मानें:
let arr = [10, 20, 40, 60];
आइए अब हम पते के शुरू होने 12
और होने के आकार पर element
विचार करें 4 bytes
।
address of arr[0] = 12 + (0 * 4) => 12
address of arr[1] = 12 + (1 * 4) => 16
address of arr[2] = 12 + (2 * 4) => 20
address of arr[3] = 12 + (3 * 4) => 24
यदि ऐसा नहीं होता zero-based
, तो तकनीकी रूप से हमारा पहला तत्व पता वही array
होता 16
जो गलत है क्योंकि यह स्थान है 12
।
ऐरे नाम एक निरंतर सूचक है जो आधार पते की ओर इशारा करता है। जब भी आप गिरफ्तारी का उपयोग करते हैं [i] संकलक इसे * (गिरफ्तारी + i) के रूप में हेरफेर करता है। जब कि int रेंज -128 से 127 हो जाती है, तो कंपाइलर को लगता है कि -128 से -1 है। ऋणात्मक संख्याएँ और 0 से 128 सकारात्मक संख्याएँ हैं। सरणी सरणी सूचकांक हमेशा शून्य से शुरू होता है।
int
कम से कम 16-बिट श्रेणी का समर्थन करने के लिए एक प्रकार की आवश्यकता होती है, और अधिकांश प्रणालियों पर इन दिनों 32-बिट्स का समर्थन करता है। मुझे लगता है कि आपका तर्क त्रुटिपूर्ण है, और आपका उत्तर वास्तव में अन्य लोगों द्वारा पहले से उपलब्ध कराए गए अन्य उत्तरों में सुधार नहीं करता है। मैं इसे हटाने का सुझाव देता हूं।