चूंकि std::list
और std::vector
मौजूद है, इसलिए सी ++ में पारंपरिक सी सरणियों का उपयोग करने का एक कारण है, या क्या उन्हें ऐसे ही टाला जाना चाहिए malloc
?
चूंकि std::list
और std::vector
मौजूद है, इसलिए सी ++ में पारंपरिक सी सरणियों का उपयोग करने का एक कारण है, या क्या उन्हें ऐसे ही टाला जाना चाहिए malloc
?
जवाबों:
C ++ 11 में जहां std::array
उपलब्ध है, उत्तर है "हाँ, सरणियों से बचा जाना चाहिए"। C ++ 11 से पहले, आपको स्वचालित भंडारण (यानी स्टैक पर) में सरणियों को आवंटित करने के लिए C सरणियों का उपयोग करने की आवश्यकता हो सकती है।
निश्चित रूप से, हालांकि std::array
C ++ 11 में, व्यावहारिक रूप से केवल स्थैतिक डेटा के लिए। C शैली सरणियों के तीन महत्वपूर्ण फायदे हैं
std::vector
:
उन्हें गतिशील आवंटन की आवश्यकता नहीं है। इस कारण से, C शैली सरणियों को प्राथमिकता दी जानी चाहिए, जहां आपको बहुत छोटे सरणियों की संभावना हो। एक n- आयाम बिंदु की तरह कुछ कहें:
template <typename T, int dims>
class Point
{
T myData[dims];
// ...
};
आमतौर पर, कोई कल्पना कर सकता है कि dims
बहुत छोटा (2 या 3),
T
एक बिल्ट-इन टाइप ( double
) होगा, और आप std::vector<Point>
लाखों तत्वों के साथ समाप्त हो सकते
हैं। आप निश्चित रूप से 3 डबल के लाखों गतिशील आवंटन नहीं चाहते हैं।
समर्थन स्थैतिक प्रारंभ। यह केवल स्थैतिक डेटा के लिए एक मुद्दा है, जहां कुछ इस तरह है:
struct Data { int i; char const* s; };
Data const ourData[] =
{
{ 1, "one" },
{ 2, "two" },
// ...
};
यह अक्सर वेक्टर (और std::string
) का उपयोग करने के लिए बेहतर होता है , क्योंकि यह आरंभीकरण के मुद्दों के सभी क्रम से बचा जाता है ; किसी भी वास्तविक कोड को निष्पादित करने से पहले डेटा को पहले से लोड किया जाता है।
अंत में, ऊपर से संबंधित, कंपाइलर इनिशियलाइज़र से सरणी के वास्तविक आकार की गणना कर सकता है। आपको उन्हें गिनने की जरूरत नहीं है।
यदि आपके पास C ++ 11 तक पहुंच है, std::array
तो पहले दो मुद्दों को हल करता है, और निश्चित रूप से पहले मामले में C शैली सरणियों के लिए प्राथमिकता में उपयोग किया जाना चाहिए। हालांकि, यह तीसरे को संबोधित नहीं करता है, और संकलक की संख्या के अनुसार सरणी आयाम होने के बावजूद अभी भी सी शैली सरणियों को पसंद करने का एक वैध कारण है।
int i[] = { 1, 2, 3 };
के साथ काम करना जारी रखता है int i[] = { 1, 2, 3, 4 };
। array<int, 3>
मैन्युअल रूप से परिवर्तित करने की आवश्यकता है array<int, 4>
।
make_array
फ़ंक्शन का उपयोग करके , make_pair
आदि जैसे हैट-टिप से @R तक। मार्टिनो फर्नांडीस ।
std::array
सी ++ 11 में, [उनका उपयोग किया जाना चाहिए] व्यावहारिक रूप से केवल स्थैतिक डेटा के लिए"।
कभी भी "कभी नहीं" कहें, लेकिन मैं सहमत हूं कि एसटीएल से सही डेटा संरचनाओं द्वारा उनकी भूमिका बहुत कम है।
मैं यह भी कहूंगा कि वस्तुओं के अंदर इनकैप्सुलेशन को इस तरह से पसंद के प्रभाव को कम करना चाहिए। यदि सरणी एक निजी डेटा सदस्य है, तो आप इसे अपनी कक्षा के ग्राहकों को प्रभावित किए बिना अंदर या बाहर स्वैप कर सकते हैं।
मैंने सुरक्षा महत्वपूर्ण प्रणालियों पर काम किया है जहाँ आप गतिशील मेमोरी आवंटन का उपयोग करने में असमर्थ हैं। मेमोरी हमेशा स्टैक पर होनी चाहिए। इसलिए इस मामले में आप सरणियों का उपयोग करेंगे क्योंकि आकार संकलन समय पर तय किया गया है।
std::array<T>
स्टैक पर आवंटित करता है और मूल रूप से कच्चे सरणी पर कोई ओवरहेड नहीं होता है।
array
में c++
देता है आप आकार गतिशील के तेजी से विकल्प तय आकार std::vector
और std::list
। std :: array , परिवर्धन में से एक है c++11
। यह सी-स्टाइल सरणियों के कुल प्रकार के शब्दार्थ प्रदान करते हुए एसटीडी कंटेनरों का लाभ प्रदान करता है।
तो c++11
मैं निश्चित रूप से उपयोग करेंगे std::array
, जहां यह आवश्यक है, वेक्टर पर। लेकिन मैं सी शैली सरणी से बचना चाहता हूँ C++03
।
आम तौर पर, नहीं , मैं कच्चे सरणियों का उपयोग करने के लिए एक कारण के बारे में नहीं सोच सकता, कहते हैं vectors
,। अगर कोड नया है ।
यदि आपके लाइब्रेरीज़ को कोड और कच्चे पॉइंटर्स की अपेक्षा करते हैं, तो आपको सरणियों का उपयोग करने का सहारा लेना पड़ सकता है।
vector.data()
C ++ 11 में या &vector.front()
पहले।
मुझे पता है कि बहुत से लोग स्टैक पर सरणी को आवंटित करने के लिए std :: array को इंगित कर रहे हैं और ढेर :: वेक्टर ढेर के लिए। लेकिन न तो गैर-देशी संरेखण का समर्थन करते हैं। यदि आप किसी भी प्रकार के संख्यात्मक कोड का उपयोग कर रहे हैं, तो आप SSE या VPX निर्देशों का उपयोग करना चाहते हैं (इस प्रकार क्रमशः 128 या 256 बाइट संरेखण की आवश्यकता होती है), C सरणियाँ अभी भी आपकी सबसे अच्छी शर्त होगी।
मैं कहूंगा कि सरणियाँ अभी भी उपयोगी हैं, यदि आप डेटा की एक छोटी स्थिर राशि का भंडारण कर रहे हैं तो क्यों नहीं।
एक सरणी का एकमात्र लाभ (निश्चित रूप से किसी चीज़ में लिपटा हुआ, जो ज़रूरत पड़ने पर स्वचालित रूप से अपने सौदे का प्रबंधन करेगा) के std::vector
बारे में मैं सोच सकता हूं कि vector
यह अपने डेटा के स्वामित्व को पारित नहीं कर सकता है, जब तक कि आपका कंपाइलर सी ++ 11 का समर्थन नहीं करता है और निर्माणकर्ताओं को स्थानांतरित नहीं करता है।
swap
।
सी शैली सरणियां एक मौलिक डेटा संरचना हैं, इसलिए ऐसे मामले होंगे जब इसका उपयोग करना बेहतर होगा। हालाँकि, सामान्य स्थिति के लिए, अधिक उन्नत डेटा संरचनाओं का उपयोग करें जो अंतर्निहित डेटा के कोनों को बंद करते हैं। सी ++ आपको मेमोरी के साथ कुछ बहुत ही रोचक और उपयोगी चीजें करने की अनुमति देता है, जिनमें से कई सरल सरणियों के साथ काम करते हैं।
std::array
s से अधिक मौलिक कैसे हैं ? दोनों कई मामलों में एक ही विधानसभा में संकलित किए जाएंगे।
std::array
स्थैतिक सरणियों के शीर्ष पर बनाया गया ठीक परिभाषित शब्दार्थ है।
आपको आंतरिक रूप से एसटीएल कंटेनरों का उपयोग करना चाहिए, लेकिन आपको अलग-अलग मॉड्यूल के बीच ऐसे कंटेनरों को पॉइंटर्स पास नहीं करना चाहिए, या आप निर्भरता नरक में समाप्त हो जाएंगे। उदाहरण:
std::string foo;
// fill foo with stuff
myExternalOutputProc(foo.c_str());
एक बहुत अच्छा समाधान है, लेकिन नहीं
std::string foo;
// fill foo with stuff
myExternalOutputProc(&foo);
कारण यह है कि std :: string को कई अलग-अलग तरीकों से लागू किया जा सकता है लेकिन एक c-style string हमेशा एक c-style string है।