সি ++ এ অ্যারে ব্যবহার করা উচিত?


97

যেহেতু std::listএবং std::vectorঅস্তিত্ব রয়েছে, তাই কি সি ++ তে প্রচলিত সি অ্যারে ব্যবহার করার কোনও কারণ আছে, বা তাদের মতো এড়ানো উচিত malloc?



18
@ অলস: এই প্রশ্নটি দুটি নির্দিষ্ট পাত্রে পার্থক্যের বিষয়ে উদ্বেগ প্রকাশ করে, অন্যদিকে এই প্রশ্নটি সাধারণভাবে কাঁচা অ্যারে এবং স্ট্যান্ডার্ড পাত্রে পার্থক্য নিয়ে উদ্বেগ প্রকাশ করে।
জন পুরে

উত্তর:


109

সি ++ ১১ এ যেখানে std::arrayপাওয়া যায়, উত্তরটি "হ্যাঁ, অ্যারেগুলি এড়ানো উচিত"। সি ++ 11 এর আগে আপনাকে স্বয়ংক্রিয় স্টোরেজে অ্যারে বরাদ্দ করতে সি অ্যারে ব্যবহার করতে হবে (যেমন স্ট্যাকের উপরে)।


4
অনেক সংকলক এখনও সি ++ 11 সমর্থন অভাব আছে।
স্টাড

4
std :: অ্যারে একটি টেমপ্লেট, যা বিল্ড টাইম এবং সম্ভবত কোড আকারের ক্ষেত্রে বৃহত প্রকল্পগুলিকে প্রভাবিত করে যেহেতু টি এর প্রতিটি সংমিশ্রণের জন্য টেমপ্লেটটি নতুনভাবে ইনস্ট্যান্ট হয়।
zvrba

std :: ভেক্টর স্ট্যান্ডার্ড অনুসারে ডেটা প্রান্তিককরণের গ্যারান্টি দেয়, সুতরাং এটি প্রায় সর্বত্র ব্যবহার করা যায়। সি ++ 11 এর সাথে সি অ্যারেগুলি ব্যবহার করার কোনও কারণ নেই।
নীল

16
@ নীল অ্যারে প্রান্তিককরণের গ্যারান্টি দেয়। এছাড়াও, স্বয়ংক্রিয় স্টোরেজ বরাদ্দ ("স্ট্যাক") গতিশীল স্টোরেজ বরাদ্দের চেয়ে অনেক দ্রুত। যদি আমি জানতে পারি যে আমার কাছে ঠিক 3 টি উপাদান রয়েছে (যেমন, ত্রিভুজের স্থানাঙ্ক], তবে ভেক্টর ব্যবহার করার কোনও কারণ নেই।
zvrba

9
@zvrba - std :: অ্যারে বনাম সি অ্যারে ব্যবহার করার সময় উত্পন্ন সমাবেশটি পরীক্ষা করুন। কোনও পার্থক্য নেই।
নেমানজা ত্রিফুনোভিচ

85

অবশ্যই, যদিও std::arrayসি ++ 11 সহ, কার্যত কেবল স্থিতিশীল ডেটার জন্য। সি স্টাইল অ্যারেগুলির তিনটি গুরুত্বপূর্ণ সুবিধা রয়েছে std::vector:

  • তাদের গতিশীল বরাদ্দ প্রয়োজন হয় না। এই কারণে, সি স্টাইলের অ্যারেগুলি অগ্রাধিকার দেওয়া উচিত যেখানে আপনার খুব কম অ্যারে হওয়ার সম্ভাবনা রয়েছে। এন-ডাইমেনশন পয়েন্টের মতো কিছু বলুন:

    template <typename T, int dims>
    class Point
    {
        T myData[dims];
    // ...
    };
    

    সাধারণত, কেউ কল্পনা করতে পারে যে dimsএটি খুব ছোট (2 বা 3), Tএকটি বিল্ট-ইন টাইপ ( double) এবং আপনি std::vector<Point>লক্ষ লক্ষ উপাদান দিয়ে শেষ করতে পারেন । আপনি অবশ্যই তিন মিলিয়ন মিলিয়ন গতিশীল বরাদ্দ চান না।

  • সমর্থন স্থিতিশীল সূচনা। এটি কেবল স্থিতিশীল ডেটার জন্যই সমস্যা, যেখানে এরকম কিছু:

    struct Data { int i; char const* s; };
    Data const ourData[] =
    {
        { 1, "one" },
        { 2, "two" },
        //  ...
    };
    

    এটি প্রায়শই কোনও ভেক্টর (এবং std::string) ব্যবহার করা পছন্দনীয় , কারণ এটি সূচনা সংক্রান্ত সমস্ত ক্রমকে এড়িয়ে চলে ; কোনও আসল কোড কার্যকর করার আগে ডেটা প্রাক লোড হয় is

  • পরিশেষে, উপরের সাথে সম্পর্কিত, সংকলক আরম্ভকারীদের থেকে অ্যারের প্রকৃত আকার গণনা করতে পারে। আপনি তাদের গণনা করতে হবে না।

আপনার যদি সি ++ 11 এ অ্যাক্সেস থাকে std::arrayতবে প্রথম দুটি সমস্যা সমাধান করে এবং প্রথম ক্ষেত্রে অবশ্যই সি স্টাইল অ্যারেগুলির পছন্দ হিসাবে ব্যবহার করা উচিত। এটি তৃতীয়টিকে সম্বোধন করে না, এবং প্রাথমিকের সংখ্যা অনুসারে সংকলক মাত্রা অ্যারে থাকা সি স্টাইল অ্যারেগুলিকে পছন্দ করার জন্য একটি বৈধ কারণ।


11
সি স্টাইলের অ্যারে ইনিশিয়ালাইজেশন নিজেকে পুনরাবৃত্তি করার প্রয়োজনীয়তাও সরিয়ে দেয়। int i[] = { 1, 2, 3 };সঙ্গে কাজ চালিয়ে যান int i[] = { 1, 2, 3, 4 };array<int, 3>ম্যানুয়ালি পরিবর্তন করতে হবে array<int, 4>

10
@ জোওয়াচেছনিগ একটি পরিবর্তন যা আপনি সহজেই ভুলে যেতে পারেন। আপনি যদি কোনও উপাদান যুক্ত করেন, সংকলকটির অভিযোগ করা উচিত, তবে আপনি যদি একটিটি সরিয়ে থাকেন, শেষে আপনি অতিরিক্ত, 0 টি প্রাথমিক উপাদান দিয়ে শেষ করবেন। আমি এখনও এই ধরণের স্ট্যাটিক ডেটার জন্য সি স্টাইল অ্যারেগুলি ব্যাপকভাবে ব্যবহার করি।
জেমস কানজে

4
প্রথম বাক্যটি বোঝায় না।
কনরাড রুডল্ফ

4
তৃতীয় পয়েন্টটি @R- এর মতো হ্যাট-টিপের অনুরূপ কোনও make_arrayফাংশন ব্যবহার করে বরং মার্জিতভাবে সমাধান করা যেতে পারে মার্টিনহো ফার্নান্দেসmake_pair
কনরাড রুডল্ফ

@ কনরাড রুডল্ফ: অবশ্যই তা করেন। আন্ড্রেয়াস জিজ্ঞাসা করেছিলেন, "সি ++ এ অ্যারে ব্যবহার করা উচিত?", জেমস জবাব দিয়েছিল যে "অবশ্যই, যদিও std::arrayসি ++ 11 এর মধ্যে [তারা ব্যবহার করা উচিত] ব্যবহারিকভাবে কেবল স্ট্যাটিক ডেটার জন্য"।
জন পুরী

15

কখনও "কখনই" বলবেন না, তবে আমি সম্মত হই যে এসটিএল থেকে সত্য ডেটা কাঠামো দ্বারা তাদের ভূমিকাটি হ্রাস পেয়েছে।

আমি আরও বলতে পারি যে বস্তুর অভ্যন্তরের এনক্যাপসুলেশনটি এই পছন্দগুলির প্রভাবকে হ্রাস করা উচিত। অ্যারেটি যদি কোনও ব্যক্তিগত ডেটা সদস্য হয় তবে আপনি নিজের শ্রেণীর ক্লায়েন্টকে প্রভাবিত না করেই এটিকে আউট বা আউট করতে পারেন।


11

আমি সুরক্ষা জটিল সিস্টেমে কাজ করেছি যেখানে আপনি গতিশীল মেমরি বরাদ্দ ব্যবহার করতে অক্ষম। স্মৃতিটি সর্বদা স্ট্যাকের মধ্যে থাকতে হবে। আকারটি সংকলনের সময় স্থির করা হওয়ায় এই ক্ষেত্রে আপনি অ্যারেগুলি ব্যবহার করবেন।


8
সি ++ 11 এর আগে আমি সম্মত হয়েছি, তবে std::array<T>স্ট্যাকগুলিতে বরাদ্দ দেয় এবং মূলত কাঁচা অ্যারেতে কোনও ওভারহেড থাকে না।
111111

5
@ 111111 - একমত তবে আমি জানি যে শিল্পের কয়েকজন লোক এখনও সি ++ 11
এড হিল

আমি জানি এ কারণেই আমি আপনাকে নিচু করতে পারি নি, তবে আমি মনে করি বুস্টের একটি সংস্করণ ছিল এবং এটি আপনার নিজের রোল করাও সহজ।
111111

6
তবে সুরক্ষার সমালোচনামূলক সিস্টেমে আপনি নতুন সংকলক বৈশিষ্ট্য (কম পরীক্ষিত) ব্যবহার করবেন না এবং আপনি বুস্ট ব্যবহার করবেন না।
জেমস কানজে 23'12

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

6

arrayইন c++আপনাকে গতিশীল আকারের std::vectorএবং স্থির আকারের দ্রুত বিকল্প দেয় std::liststd :: অ্যারে যোগ করার মধ্যে একটি c++11। এটি সি-স্টাইল অ্যারেগুলির সামগ্রিক ধরণের শব্দার্থক সরবরাহ করার সময় এটি স্ট্যান্ড পাত্রে সুবিধা দেয় provides

সুতরাং c++11আমি অবশ্যই std::arrayভেক্টর ব্যবহার করে যেখানে এটি প্রয়োজন হয়। তবে আমি সি স্টাইল অ্যারে এড়াতে চাই C++03


4

বেশিরভাগ ক্ষেত্রে, না , আমি কাঁচা অ্যারে ব্যবহার করার কোনও কারণ ভাবতে পারি না, বলুন vectorsকোডটি নতুন হলে

আপনার লাইব্রেরিগুলিতে অ্যারে এবং কাঁচা পয়েন্টার প্রত্যাশার কোডের সাথে সামঞ্জস্য হওয়া দরকার হলে আপনাকে অ্যারে ব্যবহার করতে হবে।


4
... তবে সি ++ 03 যেহেতু একজন ভেক্টরটির "আসলে" একটি অ্যারে রয়েছে, যা আপনি পয়েন্টার দ্বারা অ্যাক্সেস করতে বা পড়তে লিখতে পারেন। সুতরাং এটি কোডের বেশিরভাগ ক্ষেত্রে জুড়ে যা পয়েন্টারগুলিকে অ্যারেতে প্রত্যাশা করে। এটি কেবলমাত্র তখনই হয় যখন কোডটি অ্যারে বরাদ্দ করে বা মুক্ত করে দেয় যে আপনি কোনও ভেক্টর ব্যবহার করতে পারবেন না।
স্টিভ জেসোপ

@ স্টেজেজেপ আপনি কি অভ্যন্তরীণ অ্যারে অ্যাক্সেস করতে পারবেন?
লুচিয়ান গ্রিগোর

4
@ লুচিয়ানগ্রিগোর: vector.data()সি ++ 11 বা তার &vector.front()আগে
মাইক সিমুর

@ লুচিয়ান: প্রদত্ত ভেক্টরটি খালি না থাকলে আপনি কোনও উপাদানটিতে একটি পয়েন্টার নিতে পারেন (এবং এটি খালি থাকলে, আপনি কোনও সংবেদনশীলভাবে লিখিত ফাংশনটিতে নাল পয়েন্টার এবং 0 দৈর্ঘ্যটি পাস করতে পারেন যা কোনওটির প্রান্তের কেস গ্রহণ করে শূন্য আকারের বাফার)। সি ++ 03 তে যোগ করা ভেক্টর মিলনের গ্যারান্টির একমাত্র উদ্দেশ্য হ'ল ভেক্টরকে পয়েন্টার-ভিত্তিক কোড দ্বারা বাফার হিসাবে ব্যবহার করার অনুমতি দেওয়া।
স্টিভ জেসোপ

4
টুইট করেছেন
জেমস কানজে 23'12

4

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


3

আমি বলব অ্যারেগুলি এখনও দরকারী, যদি আপনি একটি অল্প স্থিতিশীল পরিমাণের ডেটা কেন সংরক্ষণ করেন না।


2

একটি অ্যারের কেবলমাত্র সুবিধা (অবশ্যই এমন কিছুতে আবৃত হবে যা প্রয়োজনের সাথে সাথে স্বয়ংক্রিয়ভাবে তার অবনতি পরিচালনা করবে) std::vectorএটি সম্পর্কে আমি ভাবতে পারি এটি হ'ল vectorএটির ডেটার মালিকানা পাস করতে পারে না, যদি না আপনার সংকলক সি ++ 11 সমর্থন করে এবং কনস্ট্রাক্টরকে সমর্থন করে।


6
"ভেক্টর তার ডেটার মালিকানা পাস করতে পারে না" - হ্যাঁ এটি ব্যবহার করে, C ++ 03 এ পারেন swap
স্টিভ জেসপ

2

সি স্টাইল অ্যারেগুলি একটি মৌলিক ডেটা স্ট্রাকচার, তাই এটি ব্যবহার করা ভাল হলে কেসগুলি ঘটতে পারে। তবে সাধারণ ক্ষেত্রে, আরও উন্নত ডেটা স্ট্রাকচারগুলি ব্যবহার করুন যা অন্তর্নিহিত ডেটার কোণগুলির বাইরে থাকে। সি ++ আপনাকে মেমরির সাথে খুব আকর্ষণীয় এবং দরকারী কিছু করার অনুমতি দেয়, যার মধ্যে অনেকগুলি সহজ অ্যারে ব্যবহার করে।


4
সি-স্টাইলের অ্যারেগুলি কীভাবে std::arrayএস এর চেয়ে বেশি মৌলিক ? উভয়ই অনেক ক্ষেত্রে একই সমাবেশে সংকলিত হবে।

4
এটি আরও মৌলিক যে আরও মৌলিক। আপনি কীভাবে অ্যারে যাচ্ছেন তা আপনি জানেন, স্ট্যান্ডার্ড :: অ্যারে বাস্তবায়নের গণ্ডগোল থাকতে পারে যেহেতু এটি স্ট্যান্ডার্ড লাইব্রেরির উপর নির্ভর করে।
জেমস Wynn

4
পছন্দ করেছেন std::arrayস্ট্যাটিক অ্যারেগুলির উপরে নির্মিত অবিকল শব্দার্থবিজ্ঞান রয়েছে।
কনরাড রুডল্ফ

1

আপনার অভ্যন্তরীণভাবে এসটিএল কনটেইনার ব্যবহার করা উচিত, তবে আপনাকে বিভিন্ন মডিউলগুলির মধ্যে এমন পাত্রে পয়েন্টারগুলি পাঠানো উচিত নয়, বা আপনি নির্ভরতা নরকের মধ্যে এসে পৌঁছাবেন। উদাহরণ:

std::string foo;
//  fill foo with stuff
myExternalOutputProc(foo.c_str());

একটি খুব ভাল সমাধান কিন্তু না

std::string foo;
//  fill foo with stuff
myExternalOutputProc(&foo);

কারণটি হ'ল std :: স্ট্রিংটি বিভিন্নভাবে প্রয়োগ করা যেতে পারে তবে সি-স্টাইল স্ট্রিং সর্বদা একটি সি-স্টাইল স্ট্রিং থাকে।


আমি মনে করি আপনি যা বলার চেষ্টা করছেন তা হ'ল: স্ট্যান্ডার্ড লাইব্রেরির বিভিন্ন সংকলক / প্রয়োগকারী যদি সেগুলি তৈরি করতে ব্যবহৃত হত তবে আলাদা অবজেক্ট কোডকে এক সাথে লিঙ্ক করবেন না। এটা অবশ্যই সত্য। এটি কীভাবে মূল প্রশ্নের সাথে সম্পর্কিত?
jogojapan

অ্যারে বা এসটিএল পাত্রে কখন ব্যবহার করবেন এটি কেবল একটি পরামর্শ । একটি ধারক ব্যবহার করে ডেটা তৈরি করুন, এটিকে হিসাবে পাস করুন। অন্যান্য ডেটাগুলির জন্য যে স্ট্রিংগুলিতে আপনার কিছু থাকতে পারে আমার এক্সটার্নাল আউটপুটপ্রোক (foo.rawPointerGet (), foo.count ());
ব্যবহারকারীর 877329

তবে এই সমস্যাগুলি তখনই উদ্ভূত হয় যখন আপনি একই প্রকল্পের স্ট্যান্ডার্ড লাইব্রেরির বিভিন্ন বাস্তবায়ন একত্রিত করে। এটা পাগলামি. কোডের যে কোনও সাধারণ অংশে, কোনও ভেক্টরকে কোনও ফাংশনে রেফারেন্স দ্বারা (বা, সি ++ এ, এটি সরাতে) পাস করা, পুরোপুরি ঠিক।
jogojapan

4
আমি কেবল প্লাগইনগুলি পছন্দ
করতেই পারি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.