2015-11-03 11 views
23

std::begin और std::endcontainer या array की शुरुआत और अंत को जानें।std :: end कैसे सरणी के अंत को जानता है?

end और beginvector के उदाहरण के लिए यह इतना आसान है क्योंकि यह एक वर्ग है जो यह जानकारी देता है। लेकिन, यह array के अंत की तरह कैसे जानता है?

int simple_array[5]{1, 2, 3, 4, 5}; 
auto beg=std::begin(simple_array); 
auto en=std::end(simple_array); 

std::begin यह जानना मुश्किल नहीं है कि सरणी कहां से शुरू होती है। लेकिन यह कैसे पता चलता है कि यह कहां समाप्त होता है? निरंतर पूर्णांक 5 कहीं संग्रहीत किया जाएगा?

अगर मुझे कुछ निम्न-स्तर की जानकारी के साथ उत्तर मिला तो मैं सराहना करता हूं।

उत्तर

22

निरंतर पूर्णांक 5 कुछ संग्रहीत किया जाएगा?

हां, यह सरणी के प्रकार का हिस्सा है। लेकिन नहीं, यह कहीं भी स्पष्ट रूप से संग्रहीत नहीं है। जब आप

int i[5] = { }; 

है i के प्रकार int[5] है। शाफिक का जवाब end को लागू करने के लिए इस लंबाई का उपयोग करने के तरीके के बारे में बताता है।

आप constexpr का उपयोग कर

template <typename T, size_t N> 
inline constexpr size_t 
arrLen(const T (&arr) [N]) { 
    return N; 
} 

जाना आप एक पूर्व सी ++ 11 संकलक जहां constexpr उपलब्ध नहीं है कर दिया है तो आसान तरीका, ऊपर होगा सी ++ 11, कर दिया है तो संकलन समय पर फ़ंक्शन का मूल्यांकन नहीं किया जा सकता है। तो ऐसी स्थिति में आप इस का उपयोग कर सकते हैं:

template <typename T, size_t N> 
char (&arrLenFn(const T (&arr) [N]))[N]; 

#define arrLen(arr) sizeof(arrLenFn(arr)) 

पहले हम एन char रों अर्थात sizeof की एक सरणी के लिए इस समारोह के लिए एक संदर्भ लौटने अब सरणी की लंबाई होगा एक समारोह की घोषणा। फिर हमारे पास इसे लपेटने के लिए एक मैक्रो है, ताकि यह कॉलर के अंत में पठनीय हो।

नोट: समान आधार प्रकार के दो सरणी लेकिन अलग-अलग लंबाई के साथ अभी भी दो पूरी तरह से अलग प्रकार हैं। int[3]int[2] जैसा नहीं है। Array decay, हालांकि, आपको दोनों मामलों में int* मिल जाएगा। यदि आप और जानना चाहते हैं तो How do I use arrays in C++? पढ़ें।

+0

धन्यवाद, ऐसा लगता है कि मुझे बहुत सारी चीज़ें याद आईं .. मुझे वास्तव में "एक सरणी क्या है" पूछना चाहिए .. आप का मतलब है कि सरणी किसी प्रकार की छोटी कक्षा है जो पॉइंटर शुरू करने और कई तत्वों के साथ है? क्या आप मुझे sth को इंगित कर सकते हैं कि क्या मैं इसके बारे में विवरण में पढ़ सकता हूं? –

+2

एक ही आधार प्रकार के दो सरणी लेकिन विभिन्न लंबाई के साथ अभी भी दो पूरी तरह से अलग प्रकार हैं। 'int [3]' 'int [2]' जैसा नहीं है। हालांकि, ऐरे क्षय दोनों मामलों में आपको 'int *' प्राप्त करेगा। पढ़ें [यदि मैं सरणी पर और जानना चाहता हूं, तो मैं सी ++ में सरणी का उपयोग कैसे करूं?] (Http://stackoverflow.com/q/4810664/183120)। – legends2k

+0

हां यह वही है जो मैंने आपके उत्तर से निष्कर्ष निकाला है। धन्यवाद फिर से –

24

लेकिन, यह कैसे एक सरणी

यह सरणी है, जो तब अंत सूचक निर्माण करने के लिए इस्तेमाल किया जा सकता का आकार अनुमान के लिए एक टेम्पलेट गैर प्रकार पैरामीटर का उपयोग करता है के अंत में पता है।

template< class T, std::size_t N > 
T* end(T (&array)[N]); 

HVD नोटों के रूप में, के बाद से यह संदर्भ द्वारा पारित कर दिया है कि यह एक सूचक को क्षय से बचाता है: std::end के लिए cppreference अनुभाग से सी ++ 11 हस्ताक्षर इस प्रकार है।

template< class T, std::size_t N > 
T* end(T (&array)[N]) 
{ 
    return array + N ; 
} 

निरंतर पूर्णांक 5 कुछ जहां संग्रहीत किया जाएगा है:

कार्यान्वयन के लिए कुछ इसी तरह हो सकता है?

5 या N सरणी के प्रकार का हिस्सा है और इसलिए N संकलन समय पर उपलब्ध है। उदाहरण के लिए sizeof को सरणी में लागू करने से हमें सरणी में बाइट्स की कुल संख्या मिल जाएगी।

कई बार हम किसी फ़ंक्शन के मान द्वारा पारित सरणी देखते हैं। उस स्थिति में, सरणी में संग्रहीत टाइप करने के लिए सरणी decays to a pointer। तो अब आकार की जानकारी खो गई है। संदर्भ के आधार पर हमें जानकारी के इस नुकसान से बचने और प्रकार से N आकार निकालने की अनुमति मिलती है।

+0

धन्यवाद, क्या इसका मतलब है कि एन कहीं संग्रहीत है? यदि हां, कहाँ? –

+0

एन फ़ंक्शन द्वारा संग्रहीत किया जाता है। फ़ंक्शन निष्पादित होने के बाद यह खो जाएगा। यदि आप एक ही प्रभाव प्राप्त करना चाहते हैं और सरणी के आकार को वापस लौटाना चाहते हैं तो आप इस उत्तर में दिए गए कोड का उपयोग कर सकते हैं और केवल एन –

+0

@ हुममहल्फावी को वापस कर सकते हैं, आपको पता है कि मैंने आपकी टिप्पणी के बिंदु को पहले याद किया था और जब मैं आपसे क्या कर रहा था का मतलब है। मैंने आपकी टिप्पणी को सही ढंग से कवर करने के लिए अपना उत्तर अपडेट किया। –

7

क्योंकि आप std::end पर एक सरणी पारित कर रहे हैं, और एक सरणी में T [N] टाइप किया गया है। std::end इस प्रकार में N को देख कर सरणी समाप्त होने पर बता सकता है।

संबंधित मुद्दे