std::array
सी सरणियों से काफी बेहतर है। और यहां तक कि अगर मैं विरासत कोड के साथ हस्तक्षेप करना चाहता हूं, तो मैं सिर्फ उपयोग कर सकता हूं std::array::data()
। क्या कोई कारण है कि मैं कभी भी एक पुराने स्कूल की सरणी चाहता हूँ?
std::array
सी सरणियों से काफी बेहतर है। और यहां तक कि अगर मैं विरासत कोड के साथ हस्तक्षेप करना चाहता हूं, तो मैं सिर्फ उपयोग कर सकता हूं std::array::data()
। क्या कोई कारण है कि मैं कभी भी एक पुराने स्कूल की सरणी चाहता हूँ?
जवाबों:
जब तक मैंने कुछ याद नहीं किया है (मैंने मानक में बहुत हाल के परिवर्तनों का बारीकी से पालन नहीं किया है), सी शैली सरणियों के अधिकांश उपयोग अभी भी बने हुए हैं। std::array
स्थैतिक आरंभीकरण की अनुमति देता है, लेकिन यह अभी भी आपके लिए इनिशियलाइज़र्स की गणना नहीं करेगा। और चूंकि सी शैली सरणियों का एकमात्र वास्तविक उपयोग पहले std::array
की तर्ज पर सांख्यिकीय रूप से प्रारंभिक तालिकाओं के लिए किया गया था:
MyStruct const table[] =
{
{ something1, otherthing1 },
// ...
};
उन पर पुनरावृति करने के लिए सामान्य begin
और end
टेम्पलेट फ़ंक्शंस (C ++ 11 में अपनाया गया) का उपयोग करना। कभी भी आकार का उल्लेख किए बिना, जो संकलक शुरुआती की संख्या से निर्धारित करता है।
संपादित करें: एक और बात मैं भूल गया: स्ट्रिंग शाब्दिक अभी भी सी शैली सरणियाँ हैं; प्रकार के साथ char[]
। मुझे नहीं लगता कि किसी को भी स्ट्रिंग शाब्दिक का उपयोग करने से बाहर रखा जाएगा क्योंकि हमारे पास है std::array
।
const char[]
नहीं, उह, इसे स्पष्ट रूप से रखें। और 30 अक्षरों में।
बेशक, आपको लागू करने के लिए सी सरणियों की आवश्यकता है std::array
, लेकिन यह वास्तव में एक कारण नहीं है कि कोई उपयोगकर्ता कभी भी सी सरणियां चाहता है। इसके अलावा, नहीं, std::array
सी सरणी से कम परफॉर्मेंट नहीं है, और इसमें बाउंड-चेक एक्सेस का विकल्प है। और अंत में, यह किसी भी C ++ प्रोग्राम के लिए पूरी तरह से उचित है कि वह मानक पुस्तकालय पर निर्भर हो- यह उस तरह का बिंदु है जो मानक है- और यदि आपके पास मानक पुस्तकालय तक पहुंच नहीं है, तो आपका संकलक गैर-अनुरूप है और प्रश्न "C ++" को टैग किया गया है, न कि "C ++ और उन नहीं-C ++ चीजों को जो आधे विनिर्देश को याद करते हैं क्योंकि यह अनुचित लगा।"
std::array
एक फ्रीस्टैंडिंग सी ++ 11 कार्यान्वयन में लागू नहीं कर सकता था , हालांकि।
लगता है जैसे बहुआयामी सरणियों का उपयोग सी सरणियों से आसान है std::array
। उदाहरण के लिए,
char c_arr[5][6][7];
विरोध के रूप में
std::array<std::array<std::array<char, 7>, 6>, 5> cpp_arr;
इसके अलावा, सी सरणियों की स्वचालित क्षय संपत्ति के कारण, c_arr[i]
ऊपर के उदाहरण में एक सूचक को क्षय हो जाएगा और आपको बस शेष आयामों को दो और मापदंडों के रूप में पारित करने की आवश्यकता है। मेरी बात यह c_arr
है कि नकल करना महंगा नहीं है। हालाँकि, cpp_arr[i]
कॉपी करना बहुत महंगा पड़ेगा।
array
आयामों को खोए बिना एक फ़ंक्शन के लिए बहुआयामी पास कर सकते हैं । और यदि आप इसे एक फंक्शन टेम्प्लेट में पास करते हैं, तो वह फंक्शन दोनों आयाम और प्रत्येक आयाम के आकार को घटा सकता है, या उन दोनों में से एक को भी। यह वैज्ञानिक टेम्पलेट पुस्तकालयों के लिए दिलचस्प हो सकता है जो मुख्य रूप से मनमाने आयामों पर काम करते हैं।
template <typename T, int M, int N> using array2d = std::array<std::array<T, N>, M>;
को उन मुद्दों में से किसी को हल करना चाहिए।
c_arr
है बहुत कॉपी करने के लिए महंगा! आपको ऐसा करने के लिए कोड प्रदान करना होगा। सूचक जो इसे क्षय करेगा वह प्रतिलिपि की तुलना में संदर्भ के समीप है और std::array
यदि आप चाहते हैं तो संदर्भ को पास करने के लिए उपयोग कर सकते हैं।
std::size_t
इसके बजाय ऐसा नहीं होना चाहिए int
? नाइटपैकिंग के लिए खेद है, लेकिन यह इसे सार्वभौमिक बना देगा।
size_t
हैं, हालाँकि मैं सोच भी नहीं सकता कि ऐसे कई परिदृश्य हैं जहाँ 4 बिलियन से अधिक पंक्तियों या स्तंभों के साथ सरणियाँ आवश्यक हैं।
जैसा कि सुमंत ने कहा, बहु-आयामी सरणियों के साथ-साथ सी-सरणियों में निर्मित उपयोग करने के लिए बहुत आसान है std::array
।
जब नेस्ट किया जाता है, तो std::array
पढ़ना और अनावश्यक रूप से क्रिया करना बहुत कठिन हो सकता है।
उदाहरण के लिए:
std::array<std::array<int, 3>, 3> arr1;
की तुलना में
char c_arr[3][3];
यह भी ध्यान दें begin()
, end()
और size()
जब आप घोंसला बनाते हैं , तो सभी व्यर्थ मान लौटाते हैं std::array
।
इन कारणों से मैंने अपना निश्चित आकार का बहुआयामी सरणी कंटेनर बनाया है, array_2d
और array_3d
। वे अनुरूप हैं, std::array
लेकिन 2 और 3 आयामों के बहुआयामी सरणियों के लिए। वे सुरक्षित हैं और अंतर्निहित बहुआयामी सरणियों की तुलना में कोई बुरा प्रदर्शन नहीं है। मैंने 3 से अधिक आयाम वाले बहु-आयामी सरणियों के लिए एक कंटेनर को शामिल नहीं किया क्योंकि वे असामान्य हैं। C ++ 0x में एक वैरैडिक टेम्प्लेट संस्करण बनाया जा सकता है जो एक मनमाना संख्या में आयामों का समर्थन करता है।
द्वि-आयामी संस्करण का एक उदाहरण:
//Create an array 3 x 5 (Notice the extra pair of braces)
fsma::array_2d <double, 3, 5> my2darr = {{
{ 32.19, 47.29, 31.99, 19.11, 11.19},
{ 11.29, 22.49, 33.47, 17.29, 5.01 },
{ 41.97, 22.09, 9.76, 22.55, 6.22 }
}};
पूर्ण प्रलेखन यहाँ उपलब्ध है:
http://fsma.googlecode.com/files/fsma.html
आप यहाँ पुस्तकालय डाउनलोड कर सकते हैं:
arr[x][y]
, आप यह नहीं बता सकते हैं कि arr
एरे की एक सरणी, पॉइंटर्स की एक सरणी, एक सरणी के लिए एक पॉइंटर, या पॉइंटर को एक पॉइंटर है; कार्यान्वयन के लिए सभी आपकी आवश्यकताओं के आधार पर वैध हैं। और शायद बहु-आयामी सरणियों के लिए सबसे वास्तविक दुनिया के उपयोग के मामलों को रन समय पर निर्धारित करने की आवश्यकता होती है।
C ++ में उपलब्ध C- शैली सरणियाँ वास्तव में वास्तविक C- सरणियों की तुलना में बहुत कम बहुमुखी हैं। अंतर यह है कि, सी में, सरणी प्रकारों में रनटाइम आकार हो सकते हैं । निम्नलिखित सी कोड मान्य है, लेकिन इसे न तो C ++ C- शैली सरणियों के साथ व्यक्त किया जा सकता है और न ही C ++ array<>
प्रकारों के साथ:
void foo(int bar) {
double tempArray[bar];
//Do something with the bar elements in tempArray.
}
C ++ में, आपको ढेर पर अस्थायी सरणी आवंटित करनी होगी:
void foo(int bar) {
double* tempArray = new double[bar];
//Do something with the bar elements behind tempArray.
delete[] tempArray;
}
इसे प्राप्त नहीं किया जा सकता है std::array<>
, क्योंकि bar
संकलन समय पर ज्ञात नहीं है, इसके लिए C ++ में या तो C- शैली सरणियों के उपयोग की आवश्यकता होती है std::vector<>
।
हालांकि पहला उदाहरण अपेक्षाकृत आसानी से C ++ में व्यक्त किया जा सकता है (यद्यपि आवश्यकता होती है new[]
और delete[]
), निम्नलिखित बिना C ++ में प्राप्त नहीं किया जा सकता है std::vector<>
:
void smoothImage(int width, int height, int (*pixels)[width]) {
int (*copy)[width] = malloc(height*sizeof(*copy));
memcpy(copy, pixels, height*sizeof(*copy));
for(y = height; y--; ) {
for(x = width; x--; ) {
pixels[y][x] = //compute smoothed value based on data around copy[y][x]
}
}
free(copy);
}
मुद्दा यह है कि, लाइन सरणियों के संकेत int (*)[width]
C ++ में रनटाइम चौड़ाई का उपयोग नहीं कर सकते हैं, जो सी + + में किसी भी छवि हेरफेर कोड को बहुत अधिक जटिल बनाता है। यह सी में एक विशिष्ट सी + + है। छवि हेरफेर उदाहरण का एक विशिष्ट सी ++ कार्यान्वयन इस तरह दिखेगा:
void smoothImage(int width, int height, int* pixels) {
int* copy = new int[height*width];
memcpy(copy, pixels, height*width*sizeof(*copy));
for(y = height; y--; ) {
for(x = width; x--; ) {
pixels[y*width + x] = //compute smoothed value based on data around copy[y*width + x]
}
}
delete[] copy;
}
यह कोड ठीक उसी तरह की गणना करता है जैसा कि ऊपर C कोड है, लेकिन इसे इंडेक्स कम्प्यूटेशन को हाथ से करने की आवश्यकता है जहां सूचकांक का उपयोग किया जाता है । 2 डी मामले के लिए, यह अभी भी संभव है (भले ही यह सूचकांक गणना को गलत करने के लिए बहुत सारे अवसरों के साथ आता है)। यह 3 डी मामले में वास्तव में बुरा हो जाता है, हालांकि।
मुझे C ++ में कोड लिखना पसंद है। लेकिन जब भी मुझे बहुआयामी डेटा में हेरफेर करने की आवश्यकता होती है, तो मैं वास्तव में खुद से पूछता हूं कि क्या मुझे कोड के उस हिस्से को सी में स्थानांतरित करना चाहिए।
gcc
उदाहरण के लिए) को लागू करते हैं। C11 ने काफी दिलचस्प सामान को वैकल्पिक बना दिया है, और मुझे नहीं लगता कि ऐसा इसलिए है क्योंकि वे इस सुविधा को रेखांकित करना चाहते हैं। मैं इसे एक संकेत के रूप में देखता हूं कि वे पूरी तरह से मानक अनुरूप संकलक लिखने के लिए स्तर कम करना चाहते थे: वीएलए को लागू करने के लिए काफी कठिन जानवर हैं, और बहुत से कोड बिना कर सकते हैं, इसलिए यह नए संकलक के लिए नया अर्थ देता है वीएलए के अधिकार को अभी लागू नहीं करना है।
हो सकता है std::array
कि यह धीमा न हो। लेकिन मैंने साधारण स्टोर का उपयोग करके कुछ बेंचमार्किंग की और एसटीडी :: सरणी से पढ़ा; नीचे दिए गए बेंचमार्क परिणाम देखें (W8.1, VS2013 अपडेट 4 पर):
ARR_SIZE: 100 * 1000
Avrg = Tick / ARR_SIZE;
test_arr_without_init
==>VMem: 5.15Mb
==>PMem: 8.94Mb
==>Tick: 3132
==>Avrg: 0.03132
test_arr_with_init_array_at
==>VMem: 5.16Mb
==>PMem: 8.98Mb
==>Tick: 925
==>Avrg: 0.00925
test_arr_with_array_at
==>VMem: 5.16Mb
==>PMem: 8.97Mb
==>Tick: 769
==>Avrg: 0.00769
test_c_arr_without_init
==>VMem: 5.16Mb
==>PMem: 8.94Mb
==>Tick: 358
==>Avrg: 0.00358
test_c_arr_with_init
==>VMem: 5.16Mb
==>PMem: 8.94Mb
==>Tick: 305
==>Avrg: 0.00305
नकारात्मक चिह्नों के अनुसार, मैंने जो कोड इस्तेमाल किया है वह पास्टबिन ( लिंक ) में है
बेंचमार्क क्लास कोड यहाँ है ;
मैं बेंचमार्किंग के बारे में बहुत कुछ नहीं जानता ... मेरा कोड त्रुटिपूर्ण हो सकता है
long test_arr_without_init() { return ARR_SIZE; }
void test_arr_without_init() {}
। आपको वास्तव में हुप्स के माध्यम से कूदने की ज़रूरत है यह सुनिश्चित करने के लिए कि आप जिस कोड को माप रहे हैं वह कोड है जिसे आप मापना चाहते हैं।
std::array
std::array
C सरणी से कम प्रदर्शन कैसा रहेगा।
at()
, यह अंदर की operator[]
तरह नहीं है std::vector
। कोई प्रदर्शन में कमी या कोड ब्लोट नहीं है std::array
, कंपाइलर को इस तरह की चीज़ को अनुकूलित करने के लिए डिज़ाइन किया गया है। और, ज़ाहिर है, चेक किए गए फ़ंक्शन का जोड़ एक उत्कृष्ट डिबग टूल और एक बड़ा लाभ है। @Lou फ्रेंको: सभी C ++ कोड मानक पुस्तकालय पर निर्भर हो सकते हैं- यह इस तरह का है। @ एर्लज़: यदि आपके पास एसटीएल उपलब्ध नहीं है, तो यह सी ++ नहीं है, और यह उसी का अंत है।
std::array
बराबर सी सरणी उपयोग की तुलना में बड़ा होने के लिए एक शाइनी कंपाइलर का एक नरक होना चाहिए ।