std::array
সি অ্যারেগুলির তুলনায় যথেষ্ট উন্নত। এমনকি যদি আমি লিগ্যাসি কোডের সাথে ইন্টারঅ্যাক্ট করতে চাই তবে আমি কেবল ব্যবহার করতে পারি std::array::data()
। আমি কোনও পুরানো-স্কুল অ্যারে চাইবে এমন কোনও কারণ আছে?
std::array
সি অ্যারেগুলির তুলনায় যথেষ্ট উন্নত। এমনকি যদি আমি লিগ্যাসি কোডের সাথে ইন্টারঅ্যাক্ট করতে চাই তবে আমি কেবল ব্যবহার করতে পারি std::array::data()
। আমি কোনও পুরানো-স্কুল অ্যারে চাইবে এমন কোনও কারণ আছে?
উত্তর:
আমি যদি কিছু মিস না করি (আমি স্ট্যান্ডার্ডের সাম্প্রতিক পরিবর্তনগুলি খুব কাছ থেকে অনুসরণ করি নি), সি স্টাইল অ্যারেগুলির বেশিরভাগ ব্যবহার এখনও অবধি রয়ে গেছে। std::array
স্থির সূচনা করার অনুমতি দেয়, তবে এটি এখনও আপনার জন্য আরম্ভকারীদের গণনা করবে না। এবং যেহেতু এর আগে সি স্টাইল অ্যারেগুলির একমাত্র আসল ব্যবহার std::array
ছিল স্ট্যাটিকালি আরম্ভের টেবিলগুলির লাইন বরাবর:
MyStruct const table[] =
{
{ something1, otherthing1 },
// ...
};
এগুলি পুনরাবৃত্তি করতে স্বাভাবিক begin
এবং end
টেম্পলেট ফাংশনগুলি (সি ++ 11 এ গৃহীত) ব্যবহার করে। আকারটি উল্লেখ না করেই, সংকলক আরম্ভকারীদের সংখ্যা থেকে নির্ধারণ করে।
সম্পাদনা: অন্য একটি জিনিস যা আমি ভুলে গেছি: স্ট্রিং লিটারেলগুলি এখনও সি স্টাইল অ্যারে; যেমন টাইপ সঙ্গে char[]
। আমি মনে করি না যে কেউ স্ট্রিং লিটারেল ব্যবহার করে শুধু কারণ আমরা আছে অগ্রাহ্য করবে না std::array
।
const char[]
নাহ, ধুয়ে ফেলুন। এবং 30 টি অক্ষরে
অবশ্যই, বাস্তবায়নের জন্য আপনার সি অ্যারেগুলির প্রয়োজন std::array
, তবে এটি আসলে কোনও কারণ নয় যে কোনও ব্যবহারকারী কখনই সি অ্যারে চান want এছাড়াও, না, std::array
সি অ্যারের চেয়ে কম পারফরম্যান্ট নয় এবং এতে বাউন্ডস-চেক অ্যাক্সেসের বিকল্প রয়েছে। এবং পরিশেষে, কোনও সি ++ প্রোগ্রামের জন্য স্ট্যান্ডার্ড লাইব্রেরির উপর নির্ভর করা সম্পূর্ণ যুক্তিসঙ্গত- এটি স্ট্যান্ডার্ড হওয়ার দিকটি এমন of প্রশ্নটিকে "সি ++" ট্যাগ করা হয়, "সি ++ নয় এবং সেগুলি নয়-সি ++ এমন জিনিস যা অর্ধেক স্পেসিফিকেশনটি মিস করে কারণ তারা এটিকে অনুপযুক্ত মনে করেছিল"।
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
করতে পারেন, যদিও আমি কল্পনাও করতে পারি না এমন অনেক পরিস্থিতিতে আছে যেখানে ৪ বিলিয়ন সারি বা কলামের বেশি অ্যারেগুলি প্রয়োজনীয়।
সুমেন্ট যেমন বলেছিল, সি-অ্যারে ব্যবহারের চেয়ে বহু-মাত্রিক অ্যারেগুলি ব্যবহার করা অনেক সহজ 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 টিরও বেশি মাত্রা সহ বহুমাত্রিক অ্যারেগুলির জন্য আমি কোনও ধারক অন্তর্ভুক্ত করি না কারণ তারা অস্বাভাবিক। সি ++ 0 এক্সে একটি বৈকল্পিক টেম্পলেট সংস্করণ তৈরি করা যেতে পারে যা একটি নির্বিচার সংখ্যক মাত্রাকে সমর্থন করে।
দ্বিমাত্রিক বৈকল্পিকের একটি উদাহরণ:
//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
অ্যারেগুলির একটি অ্যারে, পয়েন্টারগুলির একটি অ্যারে, বিন্যাসের বিন্দু বা বিন্দুতে পয়েন্টার কিনা ; আপনার প্রয়োজনের উপর নির্ভর করে বাস্তবায়নের জন্য সমস্ত বৈধ। এবং সম্ভবত বহুমাত্রিক অ্যারেগুলির জন্য সর্বাধিক বাস্তব-বিশ্বের ব্যবহারের ক্ষেত্রে রান সময় নির্ধারিত আকারের প্রয়োজন।
সি স্টাইলের অ্যারেগুলি সি ++ এ উপলব্ধ প্রকৃত সি-অ্যারেগুলির তুলনায় আসলে অনেক কম বহুমুখী। পার্থক্যটি হ'ল সি-তে অ্যারে প্রকারের রানটাইম মাপ থাকতে পারে। নিম্নলিখিতটি বৈধ সি কোড, তবে এটি সি ++ সি স্টাইল অ্যারে বা সি ++ array<>
প্রকারের মাধ্যমে প্রকাশ করা যাবে না :
void foo(int bar) {
double tempArray[bar];
//Do something with the bar elements in tempArray.
}
সি ++ এ আপনাকে গাদাতে অস্থায়ী অ্যারে বরাদ্দ করতে হবে:
void foo(int bar) {
double* tempArray = new double[bar];
//Do something with the bar elements behind tempArray.
delete[] tempArray;
}
এটি দিয়ে অর্জন করা যায় না std::array<>
, কারণ bar
সংকলন সময়ে জানা যায়নি, এর জন্য সি ++ বা এর মধ্যে সি-স্টাইল অ্যারে ব্যবহার করা দরকার std::vector<>
।
যদিও প্রথম উদাহরণটি তুলনামূলকভাবে সহজেই সি ++ তে প্রকাশ করা যেতে পারে (যদিও এটি প্রয়োজন হয়) new[]
এবং delete[]
) তবে নিম্নলিখিতটি সি ++ ছাড়াই অর্জন করা যায় না 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]
সি ++ তে রানটাইম প্রস্থ ব্যবহার করতে পারে না, যা কোনও চিত্রের ম্যানিপুলেশন কোডকে সি ++ এর চেয়ে বেশি জটিল করে তোলে সিটির চেয়ে একটি সাধারণ সি ++ চিত্রের ম্যানিপুলেশন উদাহরণটির বাস্তবায়নটি এর মতো দেখাবে:
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;
}
এই কোডটি অবশ্যই উপরের সি কোডের মতো একই গণনা করে, তবে সূচকগুলি যেখানে ব্যবহৃত হয় সেখানে হাত দ্বারা সূচি গণনা করা প্রয়োজন । 2 ডি কেসের ক্ষেত্রে এটি এখনও সম্ভব (যদিও সূচকের গণনাটি ভুল করার জন্য এটি প্রচুর সুযোগ নিয়ে আসে)। যদিও এটি 3 ডি ক্ষেত্রে সত্যিই বাজে।
আমি সি ++ তে কোড লেখার পছন্দ করি। তবে যখনই আমাকে বহুমাত্রিক তথ্য হস্তান্তর করা দরকার, আমি নিজেকে সত্যিই জিজ্ঞাসা করি কোডের সেই অংশটি আমার সিটিতে স্থানান্তরিত করা উচিত কিনা I
gcc
উদাহরণস্বরূপ)। সি 11 বেশ কিছু আকর্ষণীয় স্টাফ optionচ্ছিকভাবে তৈরি করেছে এবং আমি মনে করি না কারণ তারা এই বৈশিষ্ট্যটিকে ছাঁটাই করতে চায়। আমি এটিকে একটি চিহ্ন হিসাবে দেখতে চাই যে তারা একটি সম্পূর্ণ স্ট্যান্ডার্ড কমপ্লায়ার সংকলক লেখার জন্য স্তরটি কমিয়ে আনতে চেয়েছিল: ভিএলএর বাস্তবায়ন করা বেশ কঠিন জন্তু, এবং অনেক কোড ব্যতীত করতে পারে, তাই এটি কোনও নতুন ক্ষেত্রে নতুন সংকলকটির জন্য অর্থবোধ করে প্ল্যাটফর্ম এখনই VLA বাস্তবায়ন করতে হবে না।
std::array
ধীর না হতে পারে । তবে আমি সাধারণ স্টোর ব্যবহার করে কিছু বেঞ্চমার্কিং করেছি এবং স্ট্যান্ড :: অ্যারে থেকে পড়েছি; নীচের বেঞ্চমার্ক ফলাফলগুলি দেখুন (ডাব্লু 8.1, ভিএস2013 আপডেট 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
সি অ্যারের চেয়ে কম পারফরম্যান্ট হবেন আমাকে বলুন ।
at()
, এটা না operator[]
, ঠিক std::vector
। এতে কোনও কার্যকারিতা হ্রাস হয়নি বা কোড ব্লাট নেই std::array
, সংকলকটি এই ধরণের জিনিসটিকে অনুকূল করার জন্য ডিজাইন করা হয়েছে। এবং, অবশ্যই, চেক করা ফাংশন সংযোজন একটি দুর্দান্ত ডিবাগ সরঞ্জাম এবং একটি বড় সুবিধা। @ লু ফ্রাঙ্কো: সমস্ত সি ++ কোড স্ট্যান্ডার্ড লাইব্রেরির উপর নির্ভর করতে পারে - এটি এর জন্য এটি of @ ইরলজ: আপনার যদি এসটিএল উপলব্ধ না থাকে তবে এটি সি ++ নয়, এটিই শেষ।
std::array
সমতুল্য সি অ্যারের ব্যবহারের চেয়ে বড় হওয়ার জন্য আপনার কাছে একটি ছদ্মবেশী সংকলক থাকতে হবে।