এখন যে আমাদের std :: অ্যারে রয়েছে সি-স্টাইল অ্যারেগুলির জন্য কী ব্যবহারগুলি অবশিষ্ট রয়েছে?


89

std::arrayসি অ্যারেগুলির তুলনায় যথেষ্ট উন্নত। এমনকি যদি আমি লিগ্যাসি কোডের সাথে ইন্টারঅ্যাক্ট করতে চাই তবে আমি কেবল ব্যবহার করতে পারি std::array::data()। আমি কোনও পুরানো-স্কুল অ্যারে চাইবে এমন কোনও কারণ আছে?

উত্তর:


60

আমি যদি কিছু মিস না করি (আমি স্ট্যান্ডার্ডের সাম্প্রতিক পরিবর্তনগুলি খুব কাছ থেকে অনুসরণ করি নি), সি স্টাইল অ্যারেগুলির বেশিরভাগ ব্যবহার এখনও অবধি রয়ে গেছে। std::arrayস্থির সূচনা করার অনুমতি দেয়, তবে এটি এখনও আপনার জন্য আরম্ভকারীদের গণনা করবে না। এবং যেহেতু এর আগে সি স্টাইল অ্যারেগুলির একমাত্র আসল ব্যবহার std::arrayছিল স্ট্যাটিকালি আরম্ভের টেবিলগুলির লাইন বরাবর:

MyStruct const table[] =
{
    { something1, otherthing1 },
    //  ...
};

এগুলি পুনরাবৃত্তি করতে স্বাভাবিক beginএবং endটেম্পলেট ফাংশনগুলি (সি ++ 11 এ গৃহীত) ব্যবহার করে। আকারটি উল্লেখ না করেই, সংকলক আরম্ভকারীদের সংখ্যা থেকে নির্ধারণ করে।

সম্পাদনা: অন্য একটি জিনিস যা আমি ভুলে গেছি: স্ট্রিং লিটারেলগুলি এখনও সি স্টাইল অ্যারে; যেমন টাইপ সঙ্গে char[]। আমি মনে করি না যে কেউ স্ট্রিং লিটারেল ব্যবহার করে শুধু কারণ আমরা আছে অগ্রাহ্য করবে না std::array


7
আপনি একটি বৈকল্পিক ফাংশন টেম্পলেট লিখতে পারেন যা আপনাকে দৈর্ঘ্য নির্দিষ্ট করে না দিয়ে অ্যারে তৈরি করে।
রাইটফোল্ড

4
সি ++ 17 ক্লাস টেম্পলেট ছাড়ের সাথে স্বয়ংক্রিয়ভাবে ছাড়ের সংখ্যাটি সমর্থনযোগ্য। উদাহরণস্বরূপ, "অটো a = স্টিড :: অ্যারে {1, 2, 3};"
রিকি 65

Nitpick: STRING লিটারেল প্রকারconst char[]
Bulletmagnet

31

নাহ, ধুয়ে ফেলুন। এবং 30 টি অক্ষরে

অবশ্যই, বাস্তবায়নের জন্য আপনার সি অ্যারেগুলির প্রয়োজন std::array, তবে এটি আসলে কোনও কারণ নয় যে কোনও ব্যবহারকারী কখনই সি অ্যারে চান want এছাড়াও, না, std::arrayসি অ্যারের চেয়ে কম পারফরম্যান্ট নয় এবং এতে বাউন্ডস-চেক অ্যাক্সেসের বিকল্প রয়েছে। এবং পরিশেষে, কোনও সি ++ প্রোগ্রামের জন্য স্ট্যান্ডার্ড লাইব্রেরির উপর নির্ভর করা সম্পূর্ণ যুক্তিসঙ্গত- এটি স্ট্যান্ডার্ড হওয়ার দিকটি এমন of প্রশ্নটিকে "সি ++" ট্যাগ করা হয়, "সি ++ নয় এবং সেগুলি নয়-সি ++ এমন জিনিস যা অর্ধেক স্পেসিফিকেশনটি মিস করে কারণ তারা এটিকে অনুপযুক্ত মনে করেছিল"।


4
এইচএম আপনি যদি সি ++ কোড লিখছেন যা অন্য ভাষা থেকে কল পেয়েছে এবং প্যারামিটার হিসাবে পাস করার জন্য কিছু প্রয়োজন?
Asveikau

4
ফ্রিস্ট্যান্ডিং বাস্তবায়নগুলিকে প্রায় সমস্ত স্ট্যান্ডার্ড লাইব্রেরি ছেড়ে যাওয়ার অনুমতি দেওয়া হয় এবং এখনও মেনে চলতে হয়। আমার এমন একটি সংকলক সম্পর্কে গুরুতর সন্দেহ হবে যা std::arrayযদিও ফ্রিস্ট্যান্ডিং সি ++ 11 বাস্তবায়নে প্রয়োগ করতে পারে না ।
ডেনিস জিকিফুজ

11
সি ++ 0 এক্স ফাইনাল ড্রাফ্ট (ডকুমেন্ট এন 3092) § 1.4.7 "দুটি ধরণের বাস্তবায়ন সংজ্ঞায়িত করা হয়: হোস্টেড এবং ফ্রাস্ট্যান্ডিং a একটি হোস্টেড বাস্তবায়নের জন্য, এই আন্তর্জাতিক স্ট্যান্ডার্ডটি উপলব্ধ গ্রন্থাগারের সেটকে সংজ্ঞায়িত করে। কোনও অপারেটিং সিস্টেমের সুবিধা ছাড়াই স্থান গ্রহণ করে, এবং একটি নির্দিষ্টকরণের জন্য ভাষা-সমর্থন গ্রন্থাগার অন্তর্ভুক্ত রয়েছে এমন একটি গ্রন্থাগারগুলির প্রয়োগ-সংজ্ঞায়িত সেট রয়েছে ..
এসটিএলকে

24

সি-অ্যারেগুলির তুলনায় বহুমাত্রিক অ্যারে ব্যবহার করা সহজ বলে মনে হচ্ছে 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]কপি করা খুব ব্যয়বহুল হবে।


4
তবে, আপনি arrayমাত্রা হারানো ছাড়াই কোনও ফাংশনে একটি বহুমাত্রিক পাস করতে পারেন । এবং যদি আপনি এটি কোনও ফাংশন টেম্পলেটে পাস করেন তবে সেই ফাংশনটি প্রতিটি মাত্রার মাত্রা এবং আকার উভয় বা তাদের মধ্যে একটির দুটিই কেটে দিতে পারে। এটি বৈজ্ঞানিক টেম্পলেট লাইব্রেরির জন্য আকর্ষণীয় হতে পারে যা মূলত স্বেচ্ছাচারিত মাত্রা নিয়ে কাজ করে।
সেবাস্তিয়ান মাচ

31
একটি সরল এই template <typename T, int M, int N> using array2d = std::array<std::array<T, N>, M>;সমস্যার সমাধান করা উচিত।
মাইলস রাউট

7
আপনার উদাহরণটি অনুলিপি c_arrকরা খুব ব্যয়বহুল! আপনাকে নিজে কোডটি সরবরাহ করতে হবে। এতে যে পয়েন্টারটি ক্ষয় হবে সেটি হ'ল অনুলিপিটির তুলনায় একটি রেফারেন্সের সাথে সমান এবং আপনি std::arrayযদি চান তা আপনি রেফারেন্সটি পাস করতে ব্যবহার করতে পারেন।
চেটস

4
টেকনিক্যালি @ মাইলআরআউট , এর std::size_tপরিবর্তে হওয়া উচিত নয় int? নিটপিকিংয়ের জন্য দুঃখিত, তবে এটি সর্বজনীন করে তুলবে।
রবি

4
@ robbie0630 হ্যাঁ আপনি চাইলে এটি তৈরি size_tকরতে পারেন, যদিও আমি কল্পনাও করতে পারি না এমন অনেক পরিস্থিতিতে আছে যেখানে ৪ বিলিয়ন সারি বা কলামের বেশি অ্যারেগুলি প্রয়োজনীয়।
মাইলস রাউট

14

সুমেন্ট যেমন বলেছিল, সি-অ্যারে ব্যবহারের চেয়ে বহু-মাত্রিক অ্যারেগুলি ব্যবহার করা অনেক সহজ 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::array2 এবং 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

আপনি এখানে লাইব্রেরিটি ডাউনলোড করতে পারেন:

http://fsma.googlecode.com/files/fsma.zip


4
স্থির আকারের সি-স্টাইলের অ্যারেগুলি সহজ, তবে আপনি যদি মাত্রা পরিবর্তন করতে চান তবে জিনিসগুলি জটিল হয়ে যায়। উদাহরণস্বরূপ, প্রদত্ত arr[x][y], আপনি বলতে পারবেন না যে arrঅ্যারেগুলির একটি অ্যারে, পয়েন্টারগুলির একটি অ্যারে, বিন্যাসের বিন্দু বা বিন্দুতে পয়েন্টার কিনা ; আপনার প্রয়োজনের উপর নির্ভর করে বাস্তবায়নের জন্য সমস্ত বৈধ। এবং সম্ভবত বহুমাত্রিক অ্যারেগুলির জন্য সর্বাধিক বাস্তব-বিশ্বের ব্যবহারের ক্ষেত্রে রান সময় নির্ধারিত আকারের প্রয়োজন।
কিথ থম্পসন

আমি দেখতে চাই এন-ডাইমেনশনাল অ্যারেগুলির বৈচিত্র্য-টেম্পলেট-প্রয়োগকরণ! মেটা-প্রোগ্রামিং এর সেরা!
স্টিফেন

4
@ স্টেফেন আমি কয়েক বছর আগে একটি চেষ্টা করেছি। আপনি এটি এখানে দেখতে পারেন: কোড . google.com/p/fsma/source/browse/trunk/… । পরীক্ষার কেসটি এখানে: কোড . google.com/p/fsma/source/browse/trunk/… । আমি নিশ্চিত এটি যদিও আরও অনেক ভাল করা যায়।
রিকি 65

5

সি স্টাইলের অ্যারেগুলি সি ++ এ উপলব্ধ প্রকৃত সি-অ্যারেগুলির তুলনায় আসলে অনেক কম বহুমুখী। পার্থক্যটি হ'ল সি-তে অ্যারে প্রকারের রানটাইম মাপ থাকতে পারে। নিম্নলিখিতটি বৈধ সি কোড, তবে এটি সি ++ সি স্টাইল অ্যারে বা সি ++ 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


7
এটি লক্ষ করা উচিত যে কমপক্ষে ঝনঝন এবং জিসিসি সি ++ তে ভিএলএর সমর্থন করে।
জানুস ট্রয়লসেন

@ জ্যানুসটেলসন এবং এটিও যে তারা কোন উপাদানগুলির মধ্যে সমর্থন করে তা মারাত্মকভাবে সীমাবদ্ধ।
রাইটফোল্ড

সি 11 কি ভিএলএকে alচ্ছিক করে না? যদি তা হয় তবে আমি মনে করি আপনার উত্তর বিভ্রান্তিকর। এটি সঠিক হবে যখন সি 99 স্ট্যান্ডার্ড ছিল তবে সি 11 নয়।
জেড বোসন

4
@Zboson C99 একটি সি স্ট্যান্ডার্ড, এবং এমন সংকলক রয়েছে যা এর ভিএলএ বৈশিষ্ট্যগুলি প্রয়োগ করে ( gccউদাহরণস্বরূপ)। সি 11 বেশ কিছু আকর্ষণীয় স্টাফ optionচ্ছিকভাবে তৈরি করেছে এবং আমি মনে করি না কারণ তারা এই বৈশিষ্ট্যটিকে ছাঁটাই করতে চায়। আমি এটিকে একটি চিহ্ন হিসাবে দেখতে চাই যে তারা একটি সম্পূর্ণ স্ট্যান্ডার্ড কমপ্লায়ার সংকলক লেখার জন্য স্তরটি কমিয়ে আনতে চেয়েছিল: ভিএলএর বাস্তবায়ন করা বেশ কঠিন জন্তু, এবং অনেক কোড ব্যতীত করতে পারে, তাই এটি কোনও নতুন ক্ষেত্রে নতুন সংকলকটির জন্য অর্থবোধ করে প্ল্যাটফর্ম এখনই VLA বাস্তবায়ন করতে হবে না।
কাস্টমস্টার

-1

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

নেতিবাচক চিহ্ন অনুসারে, আমি যে কোডটি ব্যবহার করেছি সেটি পেস্টবিনে রয়েছে ( লিঙ্ক )

মানদণ্ডের ক্লাস কোডটি এখানে রয়েছে ;

আমি বেঞ্চমার্কিং সম্পর্কে অনেক কিছুই জানি না ... আমার কোডটি ত্রুটিযুক্ত হতে পারে


6
বেঞ্চমার্ক কোড, বা সংকলন পতাকাবিহীন বেঞ্চমার্কের ফলাফল? আসুন, আপনি আরও ভাল করতে পারেন।
আর মার্টিনহো ফার্নান্দেস

FWIW, ঠিক যে সামান্য বিট ইতিমধ্যে দেখায় যে বেঞ্চমার্ক মারাত্মক ত্রুটিযুক্ত। একটি স্মার্ট পর্যাপ্ত সংকলক পুরো জিনিসটিকে কেবল রূপান্তরিত করবেlong test_arr_without_init() { return ARR_SIZE; }
আর মার্টিনহো ফার্নান্দেস

যে শুধু একটি উদাহরণ ছিল। আমি ভেবেছিলাম এটি বড় কথা নয়। আমি অকার্যকর ফিরে আসার কোডটি পরিবর্তন করেছি, VS 2013-এ / O2 / OT / GL সহ রিলিজ বিল্ড ব্যবহৃত হয়েছে।
কে'প্রিম

রিটার্ন মান সরিয়ে দেওয়ার অর্থ কম্পাইলার পুরো জিনিসটিকে void test_arr_without_init() {}এখনই রূপান্তর করতে পারে । আপনি যে কোডটি পরিমাপ করছেন তা হ'ল কোডটি আপনি পরিমাপ করতে চান তা নিশ্চিত করতে আপনাকে সত্যই হুপসের মধ্য দিয়ে ঝাঁপিয়ে পড়তে হবে।
আর মার্টিনহো ফার্নান্দেস

-5
  1. কিছু বাস্তবায়ন std::array
  2. আপনি যদি এসটিএল ব্যবহার করতে না চান বা করতে পারেন না
  3. পারফরম্যান্সের জন্য

27
কীভাবে std::arrayসি অ্যারের চেয়ে কম পারফরম্যান্ট হবেন আমাকে বলুন ।
Xoo

4
উইকিপিডিয়া থেকে : "অ্যারে বাস্তবায়ন বাউন্ড চেক করার প্রয়োজন হয় না। তবে উত্সার প্রয়োগটি অপারেটরের জন্য এটি করে [], তবে পুনরাবৃত্তিকারীদের জন্য নয়।" - সুতরাং অপারেটর [] ধীর। আমি বাস্তবায়নের দিকে নজর দিইনি, তবে বাস্তবায়নের কোনও কোড অপ্টিমাইজারের মতো পেতে পারে।
লু ফ্রাঙ্কো

19
@Aaron McDaid: যে শুধুমাত্র আছে at(), এটা না operator[], ঠিক std::vector। এতে কোনও কার্যকারিতা হ্রাস হয়নি বা কোড ব্লাট নেই std::array, সংকলকটি এই ধরণের জিনিসটিকে অনুকূল করার জন্য ডিজাইন করা হয়েছে। এবং, অবশ্যই, চেক করা ফাংশন সংযোজন একটি দুর্দান্ত ডিবাগ সরঞ্জাম এবং একটি বড় সুবিধা। @ লু ফ্রাঙ্কো: সমস্ত সি ++ কোড স্ট্যান্ডার্ড লাইব্রেরির উপর নির্ভর করতে পারে - এটি এর জন্য এটি of @ ইরলজ: আপনার যদি এসটিএল উপলব্ধ না থাকে তবে এটি সি ++ নয়, এটিই শেষ।
কুকুরছানা

6
@ এয়ারলজ: সি ++ স্ট্যান্ডার্ডটিতে স্ট্যান্ডার্ড লাইব্রেরি রয়েছে। আপনি যদি গ্রন্থাগারটি ব্যবহার করতে না পারেন, তবে এটি উপযুক্ত নয়। এবং দ্বিতীয়ত, std::arrayসমতুল্য সি অ্যারের ব্যবহারের চেয়ে বড় হওয়ার জন্য আপনার কাছে একটি ছদ্মবেশী সংকলক থাকতে হবে।
কুকুরছানা

4
@ এয়ারলজ: "বেশিরভাগ অনুসারে নয়" এবং "নিখুঁত বৈশিষ্ট্যগুলি যা বিশদ বিবরণে শত শত পৃষ্ঠা" এর মধ্যে একটি বড় পার্থক্য রয়েছে।
কুকুরছানা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.