স্ট্যান্ড :: ভেক্টর বনাম স্টাড :: সি ++ এ অ্যারে


283

সি ++ এ std::vectorএবং এ এর মধ্যে পার্থক্য কী std::array? কখন একজনকে অন্যের চেয়ে বেশি পছন্দ করা উচিত? প্রতিটি আগপাছ কি হয়? আমার সমস্ত পাঠ্যপুস্তক কীভাবে সেগুলি একই তা তালিকাভুক্ত করে।


1
আমি std::vectorবনামের তুলনা std::arrayএবং শর্তগুলি কীভাবে আলাদা তা খুঁজছি ।
Zud

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

আপনার ব্যাখ্যাটি প্রতিবিম্বিত করতে আমি প্রশ্নের শিরোনাম এবং পাঠ্য আপডেট করেছি।
মাত্তেও ইটালিয়া

উত্তর:


318

std::vectorহ'ল একটি টেম্পলেট শ্রেণি যা হিপগুলিতে সঞ্চিত একটি গতিশীল অ্যারে 1 সজ্জিত করে, যা উপাদানগুলি যুক্ত করা বা অপসারণ করা হলে স্বয়ংক্রিয়ভাবে বৃদ্ধি এবং সঙ্কুচিত হয়। এটি সমস্ত হুক সরবরাহ করে ( begin(),, end()পুনরুদ্ধারকারী, ইত্যাদি) যা এটি এসটিএল এর বাকী অংশের সাথে দুর্দান্তভাবে কাজ করে। এটিতে বেশ কয়েকটি দরকারী পদ্ধতি রয়েছে যা আপনাকে এমন ক্রিয়াকলাপ সম্পাদন করতে দেয় যা একটি সাধারণ অ্যারেতে জটিল হয়ে উঠবে যেমন উদাহরণস্বরূপ কোনও ভেক্টরের মাঝখানে উপাদানগুলি সন্নিবেশ করানো (এটি নীচের উপাদানগুলিকে পর্দার পিছনে সরানোর সমস্ত কাজ পরিচালনা করে)।

যেহেতু এটি স্তূপে বরাদ্দকৃত মেমরির উপাদানগুলিকে সঞ্চয় করে, তাই এটি স্ট্যাটিক অ্যারেগুলির ক্ষেত্রে কিছুটা ওভারহেড থাকে।

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

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

একটি পরিচিতির জন্য std::array, এই নিবন্ধটি একবার দেখুন ; std::vectorএটিতে যে ক্রিয়াকলাপ সম্ভব তাড়াতাড়ি পরিচয় করিয়ে দেওয়ার জন্য, আপনি এর ডকুমেন্টেশনটি দেখতে চাইতে পারেন ।


  1. প্রকৃতপক্ষে, আমি মনে করি যে স্ট্যান্ডার্ডে এগুলি বিভিন্ন অপারেশনের সর্বাধিক জটিলতার পরিপ্রেক্ষিতে বর্ণিত হয়েছে (যেমন ধ্রুবক সময়ে এলোমেলো অ্যাক্সেস, লিনিয়ার সময়ে সমস্ত উপাদানগুলির উপর পুনরাবৃত্তি, ধ্রুবক মোড়িত সময়ের শেষে উপাদানগুলি যুক্ত এবং অপসারণ, ইত্যাদি), তবে এএফআইএকে ডায়নামিক অ্যারে ব্যবহার করা ছাড়া এ জাতীয় প্রয়োজনীয়তাগুলি পূরণের অন্য কোনও পদ্ধতি নেই। @ লুক্রেটিয়ালের বিবরণ অনুসারে, মানকটির আসলে প্রয়োজন হয় যে উপাদানগুলি স্বচ্ছলভাবে সংরক্ষণ করা হয়, সুতরাং এটি একটি গতিশীল অ্যারে, যেখানে সম্পর্কিত বরাদ্দকারী এটি রাখে সেখানে সঞ্চিত হয়।

6
আপনার পাদটীকা সম্পর্কে: সত্য হলেও, মানটি গ্যারান্টি দেয় যে অভ্যন্তরীণ উপাদানগুলিতে পয়েন্টার গাণিতিক কাজ করে, যার অর্থ এটি একটি অ্যারে হওয়া দরকার: & vec [9] - এবং উপাচার্য [3] == 6 সত্য।
লুক্রেটিয়েল

9
আমি বেশ নিশ্চিত, যে ভেক্টরটি স্বয়ংক্রিয়ভাবে সঙ্কুচিত হয় না, তবে সি ++ 11 যেহেতু আপনি সংকোচ_কে_ফিট কল করতে পারেন।
দিনো

স্ট্যাটিক অ্যারে শব্দটি দ্বারা আমি সম্পূর্ণ বিভ্রান্ত এবং সঠিক পরিভাষাটি কী তা নিশ্চিত। আপনার অর্থ স্ট্যাটিক সাইজের অ্যারে এবং স্ট্যাটিক ভেরিয়েবল অ্যারে নয় (স্ট্যাটিক স্টোরেজ ব্যবহার করা একটি)। stackoverflow.com/questions/2672085/… । সঠিক পরিভাষা কী? স্থির অ্যারেটি কোনও স্থির আকারের সাথে কোনও অ্যারের জন্য একটি opড়ু শব্দ?
জেড বোসন

3
@ জবসন: এটি অবশ্যই আপনি নন, স্থিতিশীল বেশ আপত্তিজনক শব্দ; staticসি ++ এর খুব কীওয়ার্ডটির তিনটি ভিন্ন সম্পর্কহীন অর্থ রয়েছে এবং শব্দটি সংকলনের সময় স্থির করা স্টাফ নিয়ে কথা বলতে প্রায়শই ব্যবহৃত হয়। আমি আশা করি "স্ট্যাটিকালি আকারের" কিছুটা আরও পরিষ্কার।
মাত্তেও ইতালি

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

17

std::vector<T>ক্লাস ব্যবহার :

  • ... অন্তর্নির্মিত অ্যারেগুলি ব্যবহার করার মতোই দ্রুত , ধরে নেওয়া আপনি কেবল বিল্ট-ইন অ্যারেগুলি যা করার অনুমতি দিচ্ছেন তা করছেন (বিদ্যমান উপাদানগুলিকে পড়ুন এবং লিখুন)।

  • ... নতুন উপাদান areোকানো হলে স্বয়ংক্রিয়ভাবে আকার পরিবর্তন করে।

  • ... আপনাকে শুরুতে বা ভেক্টরের মাঝামাঝি সময়ে নতুন উপাদানগুলি সন্নিবেশ করতে দেয় , স্বয়ংক্রিয়ভাবে বাকি উপাদানগুলিকে "উপরে" স্থানান্তরিত করে (এটি কী বোঝায়?) এটি আপনাকে অন্যান্য যে কোনও উপাদানগুলিকে std::vectorস্বয়ংক্রিয়ভাবে নীচে স্থানান্তরিত করতে খুব সহজেই যে কোনও জায়গায় উপাদান সরিয়ে ফেলতে দেয়।

  • ... আপনাকে at()পদ্ধতির সাহায্যে একটি পরিসীমা-পরীক্ষিত পাঠ সম্পাদন করতে দেয় (আপনি []যদি এই চেকটি সম্পাদন করতে না চান তবে আপনি সর্বদা সূচকগুলি ব্যবহার করতে পারেন)।

ব্যবহারের জন্য দুটি প্রধান ক্যাভেট রয়েছে std::vector<T>:

  1. অন্তর্নিহিত পয়েন্টারটিতে আপনার কাছে নির্ভরযোগ্য অ্যাক্সেস নেই, আপনি যদি কোনও অ্যারের ঠিকানার দাবি করে এমন তৃতীয় পক্ষের ফাংশনগুলি নিয়ে কাজ করছেন তবে এটি একটি সমস্যা হতে পারে।

  2. std::vector<bool>বর্গ নিরীহ নয়। এটি কনডেনড বিটফিল্ড হিসাবে প্রয়োগ করা হয়েছে, অ্যারে হিসাবে নয়। আপনি যদি একটি অ্যারের চান তা এড়িয়ে চলুন bool!

  3. ব্যবহারের সময়, std::vector<T>গুলি একই সংখ্যক উপাদানগুলির সাথে সি ++ অ্যারের চেয়ে কিছুটা বড় হতে চলেছে। এটি এ কারণেই তাদের সামান্য পরিমাণে অন্যান্য তথ্যের যেমন তাদের বর্তমান আকারের উপর নজর রাখতে হবে এবং যখনই std::vector<T>আকার পরিবর্তন করা হয় তখন তাদের আরও স্থান সংরক্ষণ করা হয় তবে তাদের প্রয়োজন। এটি হ'ল প্রতিবারই কোনও নতুন উপাদান isোকানোর সময় তাদের আকার পরিবর্তন করতে বাধা দেওয়া। একটি কাস্টম সরবরাহ করে এই আচরণটি পরিবর্তন করা যেতে পারে allocator, তবে আমি কখনই তা করার প্রয়োজন অনুভব করি নি!


সম্পাদনা: প্রশ্নের জুদ এর উত্তর পড়ার পরে, আমি অনুভব করেছি আমার এটি যুক্ত করা উচিত:

std::array<T>বর্গ একটি সি ++ অ্যারে হিসাবে একই নয়। std::array<T>ক্লাসের ব্যবহারকারীর কাছ থেকে পয়েন্টারটি গোপন করার প্রাথমিক উদ্দেশ্য সহ সি ++ অ্যারের চারপাশে একটি খুব পাতলা মোড়ক রয়েছে (সি ++ তে অ্যারেগুলি স্পষ্টতই পয়েন্টার হিসাবে নিক্ষেপ করা হয়, প্রায়শই বিরক্তিকর প্রভাবের জন্য)। std::array<T>শ্রেণী তার আকার (দৈর্ঘ্য), যা খুবই উপযোগী হতে পারে সঞ্চয় করে।


5
এটা 'শুধু দ্রুত হিসাবে "একটি পরিবর্তনশীল-বরাদ্দ বিল্ট-ইন অ্যারের অন্যদিকে, একটি স্বয়ংক্রিয় বিন্যাস ব্যবহার (কারণ এলাকার প্রভাব বরাদ্দ সময় না শুধুমাত্র এবং,) যথেষ্ট বিভিন্ন কর্মক্ষমতা থাকতে পারে ব্যবহার
বেন Voigt

4
সি ++ 11 অ bool, ভেক্টর জন্য এবং পরে, আপনি কল করতে পারেন data()একটি উপর std::vector<T>অন্তর্নিহিত পয়েন্টার জন্য। আপনি কেবল 0 এলিমেন্টের ঠিকানা নিতে পারেন (সি ++ 11 এর সাথে কাজ করার গ্যারান্টিযুক্ত, সম্ভবত পূর্ববর্তী সংস্করণগুলির সাথে কাজ করবে)।
ম্যাট

16

@ মাত্তিও ইটালিয়া দ্বারা তৈরি একটি পয়েন্টকে জোর দেওয়ার জন্য, দক্ষতার পার্থক্যটি যেখানে ডেটা সংরক্ষণ করা হয়। হিপ মেমরির (সাথে প্রয়োজনীয় vector) মেমরি বরাদ্দের জন্য সিস্টেমে একটি কল প্রয়োজন এবং আপনি চক্র গণনা করা হলে এটি ব্যয়বহুল হতে পারে। স্ট্যাক মেমোরি (এর জন্য সম্ভব array) সময়ের নিরিখে কার্যত "শূন্য-ওভারহেড", কারণ মেমরিটি কেবল স্ট্যাক পয়েন্টারটি সামঞ্জস্য করে বরাদ্দ করা হয় এবং এটি কোনও ফাংশনে প্রবেশের পরে একবারে সম্পন্ন হয়। স্ট্যাকটি মেমরির খণ্ডনও এড়িয়ে যায়। নিশ্চিত হওয়া, std::arrayসবসময় স্ট্যাকের উপরে থাকবে না; এটি আপনি কোথায় এটি বরাদ্দ করেছেন তার উপর নির্ভর করে তবে এটি ভেক্টরের তুলনায় এটি গাদা থেকে একটি কম মেমরি বরাদ্দকে জড়িত করবে। যদি তোমার কাছে থাকে একটা

  • ছোট "অ্যারে" (100 টি উপাদানগুলির নীচে বলে) - (একটি সাধারণ স্ট্যাকটি প্রায় 8MB, তাই আপনার কোডটি পুনরাবৃত্তি হলে স্ট্যাকের কয়েক কেবি বা তারও বেশি বরাদ্দ করবেন না)
  • আকার ঠিক করা হবে
  • আজীবন কার্যক্ষেত্রে রয়েছে (বা প্যারেন্ট ক্লাসের মতো একই জীবনকাল সহ একটি সদস্যের মান)
  • আপনি চক্র গণনা করছেন,

অবশ্যই একটি std::arrayওভার ভেক্টর ব্যবহার করুন । যদি সেই প্রয়োজনীয়তাগুলির কোনওটি সত্য না হয় তবে একটি ব্যবহার করুন std::vector


3
চমৎকার উত্তর. "নিশ্চিত হওয়ার জন্য, std :: অ্যারে সর্বদা স্ট্যাকের উপরে থাকবে না; এটি আপনি কোথায় বরাদ্দ করেছেন তার উপর নির্ভর করে" সুতরাং আমি কীভাবে একটি std :: অ্যারে তৈরি করতে পারি যাতে বিপুল সংখ্যক উপাদান সহ স্ট্যাকের উপরে নয়?
ট্রেলারিয়ান

4
@ new std::arrayট্রিলারিয়ন আপনি বরাদ্দ দেওয়ার জন্য 'নতুন' ব্যবহার করেন এমন শ্রেণীর সদস্য বা ব্যবহার করুন।
লাকাটা

সুতরাং এর অর্থ new std::arrayএখনও সঙ্কলনকালে এর আকারটি জানতে পারে এবং এর আকার পরিবর্তন করতে পারে না তবে এখনও স্তূপে বাস করে?
ট্রিপলিয়ন

হ্যাঁ. new std::arrayবনাম ব্যবহারের কোনও উল্লেখযোগ্য সুবিধা নেই new std::vector
লাকাটা

12

আপনি যদি বহুমাত্রিক অ্যারেগুলি ব্যবহারের বিষয়টি বিবেচনা করছেন তবে স্ট্যান্ড :: অ্যারে এবং স্টাড :: ভেক্টরের মধ্যে আরও একটি পার্থক্য রয়েছে। একটি বহুমাত্রিক std :: অ্যারেতে এসি স্টাইল অ্যারে যেমন রয়েছে তেমনি সমস্ত মাত্রায় মেমোরিতে প্যাক করা উপাদান থাকবে। একটি বহুমাত্রিক std :: ভেক্টর সমস্ত মাত্রায় প্যাক করা হবে না।

নিম্নলিখিত ঘোষণা দেওয়া:

int cConc[3][5];
std::array<std::array<int, 5>, 3> aConc;
int **ptrConc;      // initialized to [3][5] via new and destructed via delete
std::vector<std::vector<int>> vConc;    // initialized to [3][5]

সি-স্টাইল অ্যারেতে প্রথম উপাদানটির একটি পয়েন্টার (সিসনক) বা স্টাডি :: অ্যারে (একনক) প্রতিটি পূর্ববর্তী উপাদানকে 1 যোগ করে পুরো অ্যারের মাধ্যমে পুনরাবৃত্তি করা যেতে পারে। তারা শক্তভাবে প্যাক করা হয়।

ভেক্টর অ্যারেতে প্রথম উপাদানটির একটি পয়েন্টার (ভিঙ্কনসি) বা পয়েন্টার অ্যারে (পিটিআরসিএনসি) কেবল প্রথম 5 (এই ক্ষেত্রে) উপাদানগুলির মাধ্যমে পুনরাবৃত্তি করা যেতে পারে এবং তারপরে ওভারহেডের 12 টি বাইট (আমার সিস্টেমে) থাকে পরবর্তী ভেক্টর

এর অর্থ হ'ল একটি স্টাডি :: ভেক্টর> অ্যারে হিসাবে [3] [1000] অ্যারে হিসাবে আরম্ভ করা একটি [1000] [3] অ্যারে হিসাবে আরম্ভ করা মেমরির চেয়ে অনেক ছোট হবে, এবং উভয়ই স্ট্যান্ডের চেয়ে মেমরির চেয়ে বড় হবে: অ্যারে উভয় উপায়ে বরাদ্দ।

এর অর্থ হ'ল আপনি কেবল মেমরির ওভারহেডের জন্য অ্যাকাউন্টিং না করেই ওপেনজিএল বলতে, কোনও বহুমাত্রিক ভেক্টর (বা পয়েন্টার) সরাতে পারবেন না, তবে আপনি নির্লজ্জভাবে ওপেনগিএল একটি বহুমাত্রিক স্ট্যান্ড :: অ্যারে পাস করতে পারেন এবং এটি কার্যকর করতে পারেন।


-17

একটি ভেক্টর একটি ধারক শ্রেণি এবং অ্যারে বরাদ্দকৃত মেমরি।


23
আপনার উত্তর ঠিকানা বলে মনে হয় std::vector<T>বনাম T[]কিন্তু প্রশ্ন সম্পর্কে std::vector<T>বনাম std::array<T>
কীথ পিনসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.