वैक्टर बनाम एरेस: इंट्रोडक्टरी समानता और अंतर [बंद]


111

C ++ में एक सरणी और एक वेक्टर के बीच अंतर क्या हैं? मतभेदों का एक उदाहरण पुस्तकालयों, प्रतीकवाद, क्षमताओं आदि को शामिल किया जा सकता है।

सरणी

Arrays में एक विशेष प्रकार के तत्वों की एक विशिष्ट संख्या होती है। ताकि संकलक अंतरिक्ष की आवश्यक मात्रा आरक्षित कर सके जब कार्यक्रम संकलित किया जाता है, तो आपको उन तत्वों के प्रकार और संख्या को निर्दिष्ट करना होगा जो सरणी में परिभाषित होने पर शामिल होंगे। कंपाइलर इस मान को निर्धारित करने में सक्षम होना चाहिए जब प्रोग्राम संकलित किया जाता है। एक बार एक सरणी को परिभाषित करने के बाद, आप सरणी के विशिष्ट तत्वों तक पहुंचने के लिए एक सूचकांक के साथ सरणी के लिए पहचानकर्ता का उपयोग करते हैं। [...] सरणियाँ शून्य-अनुक्रमित हैं; वह पहला तत्व है, जो इंडेक्स 0. पर है। यह इंडेक्सिंग योजना सूचक और सरणियों के बीच C ++ में घनिष्ठ संबंध और सूचक अंकगणित के लिए भाषा को परिभाषित करने वाले नियमों का सूचक है।

- सी ++ पॉकेट संदर्भ

वेक्टर

एक वेक्टर वस्तुओं के एक गतिशील आकार का अनुक्रम है जो सरणी-शैली operator[]यादृच्छिक अभिगम प्रदान करता है । सदस्य फ़ंक्शन push_backकॉपी कंस्ट्रक्टर के माध्यम से अपने तर्कों को कॉपी करता है, वेक्टर में अंतिम आइटम के रूप में उस कॉपी को जोड़ता है और एक-एक करके उसका आकार बढ़ाता है।pop_backअंतिम तत्व को हटाकर, सटीक विपरीत करता है। किसी वेक्टर के अंत से आइटम सम्मिलित करना या हटाना निरंतर समय लेता है, और किसी अन्य स्थान से रैखिक समय में सम्मिलित या हटा रहा है। ये वैक्टर की मूल बातें हैं। उनके लिए और भी बहुत कुछ है। ज्यादातर मामलों में, C-style array पर एक वेक्टर आपकी पहली पसंद होना चाहिए। सबसे पहले, वे गतिशील रूप से आकार लेते हैं, जिसका अर्थ है कि वे आवश्यकतानुसार बढ़ सकते हैं। आपको एक इष्टतम स्थिर आकार का पता लगाने के लिए सभी प्रकार के अनुसंधान करने की आवश्यकता नहीं है, जैसा कि सी सरणियों के मामले में है; एक वेक्टर आवश्यकतानुसार बढ़ता है, और यदि आप की आवश्यकता होती है तो इसे बड़े या छोटे रूप से आकार दिया जा सकता है। दूसरे, वैक्टर atसदस्य फ़ंक्शन के साथ सीमा जाँच की पेशकश करते हैं (लेकिन साथ नहींoperator[]), ताकि आप कुछ कर सकें, यदि आप अपने प्रोग्राम को क्रैश या खराब होने के बजाय एक अस्पष्ट सूचकांक का संदर्भ देते हैं, तो भ्रष्ट डेटा के साथ निष्पादन जारी है।

- सी ++ कुकबुक


सबसे बुनियादी अंतर: ऐसे उद्देश्य हैं जिनके लिए वेक्टर एक अच्छा विकल्प है।
जेरी कॉफिन

1
"एग्जॉस्टिव" और "कॉन्सेज़" ऑर्थोगोनल हैं। यही है, न केवल एक दूसरे को नहीं करता है , बल्कि वे एक ही पैमाने पर भी नहीं हैं।
ऑर्बिट में लाइटनेस दौड़

2
मैं लोगों को वास्तव में परेशान करता हूं कि करीबी प्रश्न जो वास्तव में जानकारी है जो मैं देख रहा हूं। ऐसा अक्सर होता है।
रॉबर्ट टैमलिन

जवाबों:


142

सरणियों:

  • एक बिलियन लैंग्वेज कंस्ट्रक्शन हैं;
  • आओ C89 से लगभग unmodified;
  • तत्वों का सिर्फ एक सन्निहित, अनुक्रमिक अनुक्रम प्रदान करते हैं ; कोई घंटी और सीटी नहीं;
  • निश्चित आकार के हैं; आप C ++ में एक सरणी का आकार परिवर्तन नहीं कर सकते (जब तक कि यह POD की एक सरणी न हो और इसके साथ आवंटित न हो malloc);
  • जब तक उन्हें गतिशील रूप से आवंटित नहीं किया जाता है, उनका आकार एक संकलन-समय स्थिर होना चाहिए;
  • वे अपने भंडारण स्थान को उस दायरे से निर्भर करते हैं जहां आप उन्हें घोषित करते हैं;
  • यदि गतिशील रूप से आवंटित किया गया है, तो आपको उन्हें स्पष्ट रूप से निपटाना होगा;
  • यदि वे गतिशील रूप से आवंटित किए जाते हैं, तो आपको केवल एक संकेतक मिलता है, और आप उनका आकार निर्धारित नहीं कर सकते हैं; अन्यथा, आप उपयोग कर सकते हैं sizeof(इसलिए सामान्य मुहावरे sizeof(arr)/sizeof(*arr), जो किसी सूचक पर अनजाने में उपयोग किए जाने पर चुपचाप विफल हो जाते हैं);
  • ज्यादातर स्थितियों में स्वचालित रूप से एक संकेत करने के लिए क्षय; विशेष रूप से, यह तब होता है जब उन्हें किसी फ़ंक्शन में पास किया जाता है, जिसे आमतौर पर उनके आकार के लिए एक अलग पैरामीटर पारित करने की आवश्यकता होती है;
  • एक समारोह से वापस नहीं किया जा सकता है;
  • सीधे कॉपी / असाइन नहीं किया जा सकता है;
  • वस्तुओं के गतिशील सरणियों के लिए एक डिफ़ॉल्ट निर्माता की आवश्यकता होती है, क्योंकि उनके सभी तत्वों का निर्माण पहले किया जाना चाहिए;

std::vector:

  • एक टेम्पलेट वर्ग है;
  • C ++ केवल निर्माण है;
  • एक गतिशील सरणी के रूप में कार्यान्वित किया जाता है ;
  • बढ़ता है और गतिशील रूप से सिकुड़ता है;
  • स्वचालित रूप से उनकी स्मृति का प्रबंधन करता है, जिसे विनाश पर मुक्त किया जाता है;
  • पारित किया जा सकता है / कार्यों से लौटा (मूल्य से);
  • कॉपी / असाइन किया जा सकता है (यह सभी संग्रहीत तत्वों की एक गहरी प्रतिलिपि करता है);
  • संकेत करने के लिए क्षय नहीं है, लेकिन आप स्पष्ट रूप से उनके डेटा के लिए एक संकेतक प्राप्त कर सकते हैं ( &vec[0]उम्मीद के मुताबिक काम करने की गारंटी है);
  • हमेशा आंतरिक गतिशील सरणी के साथ अपने आकार को लाता है (वर्तमान में कितने तत्व संग्रहीत हैं) और क्षमता ( वर्तमान में आवंटित तत्वों में कितने तत्व संग्रहीत किए जा सकते हैं );
  • आंतरिक गतिशील सरणी को ऑब्जेक्ट के अंदर आवंटित नहीं किया जाता है (जिसमें बस कुछ "बहीखाता" फ़ील्ड शामिल हैं), लेकिन प्रासंगिक टेम्पलेट पैरामीटर में निर्दिष्ट आवंटनकर्ता द्वारा गतिशील रूप से आवंटित किया गया है; डिफ़ॉल्ट को फ़्रीस्टोर (तथाकथित ढेर) से मेमोरी मिलती है, स्वतंत्र रूप से कैसे वास्तविक वस्तु आवंटित की जाती है;
  • इस कारण से, वे छोटे, अल्पकालिक, स्थानीय सरणियों के लिए "नियमित" सरणियों की तुलना में कम कुशल हो सकते हैं;
  • जब reallocating, वस्तुओं को कॉपी किया जाता है (स्थानांतरित, C ++ 11 में);
  • संग्रहीत की जा रही वस्तुओं के लिए एक डिफ़ॉल्ट निर्माता की आवश्यकता नहीं है;
  • बेहतर तथाकथित STL के साथ एकीकृत है (यह begin()/ end()तरीके प्रदान करता है , सामान्य STL typedefs, ...)

सरणियों के लिए "आधुनिक विकल्प" पर भी विचार करें - std::array; मैंने पहले से ही एक और जवाब में अंतर का वर्णन किया है std::vectorऔर std::array, आप इसे देखना चाहते हैं।


1
साभार, @ मत्तो इतालिया एक संदर्भ या दो अच्छा होगा।
ट्रानकोट

1
@ ट्रॅनकोट: कोई भी अच्छा सी ++ बुक करेगा।
मट्टियो इटालिया

6
@ ट्रॅनकोट: मैं वास्तव में आपको ज्यादा बेहतर संदर्भ नहीं दे सकता - इस पोस्ट में हाइलाइट किए गए अंतर मानक के विभिन्न भागों से आते हैं, और एक अच्छे C ++ मैनुअल की मदद से बेहतर समझे जाते हैं।
मट्टियो इटालिया

इस तरह के एक व्यापक विवरण का एक उदाहरण महान होगा!
कार्लास्वामी 85

26

मैं जोड़ता हूँ कि सरणियाँ C ++ में बहुत ही निम्न-स्तर के निर्माण हैं और आपको "रस्सियों को सीखते समय" जितना संभव हो सके उनसे दूर रहने की कोशिश करनी चाहिए - यहां तक ​​कि ब्रेज़न स्ट्रॉस्ट्रुप इसकी अनुशंसा करता है (वह C ++ का डिजाइनर है)।

वैक्टर्स सरणियों के समान प्रदर्शन के बहुत करीब आते हैं, लेकिन एक महान कई उपयुक्तताओं और सुरक्षा सुविधाओं के साथ। जब आप API के साथ तालमेल बिठाते हैं तो कच्चे सरणियों के साथ या अपने स्वयं के संग्रह का निर्माण करते समय आप संभवतः सरणियों का उपयोग करना शुरू कर देंगे।


1
आवेदन कार्यक्रम इंटरफ़ेस: ( en.wikipedia.org/wiki/API )। यह एक सॉफ्टवेयर इकाई (पैकेज, लाइब्रेरी, ऑपरेटिंग सिस्टम) में प्रवेश बिंदुओं का एक संग्रह है। कुछ API में एंट्री पॉइंट होंगे जैसे strcat (char * dst, char * src), जहाँ dst और src को कैरेक्टर्स के सरणियों के रूप में माना जाता है (भले ही फ़ंक्शन सिग्नेचर से संकेत मिलता है कि अक्षर)।
जॉन कैलेन

11

उन संदर्भों ने आपके प्रश्न का बहुत उत्तर दिया। सीधे शब्दों में, वैक्टर की लंबाई गतिशील होती है जबकि सरणियों का एक निश्चित आकार होता है। किसी सरणी का उपयोग करते समय, आप घोषणा पर उसका आकार निर्दिष्ट करते हैं:

int myArray[100];
myArray[0]=1;
myArray[1]=2;
myArray[2]=3;

वैक्टर के लिए, आप इसे घोषित करते हैं और तत्वों को जोड़ते हैं

vector<int> myVector;
myVector.push_back(1);
myVector.push_back(2);
myVector.push_back(3);
...

कई बार आप जानते हैं कि तत्वों की संख्या की आवश्यकता होती है, इसलिए वेक्टर ऐसी स्थिति के लिए आदर्श होगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.