একটি অ্যারের সমস্ত উপাদান সি ++ তে একটি ডিফল্ট মানতে শুরু করা?


248

সি ++ নোটস: অ্যারে ইনিশিয়ালাইজেশনে অ্যারে সূচনা করার ক্ষেত্রে একটি দুর্দান্ত তালিকা রয়েছে। আমার আছে একটি

int array[100] = {-1};

এটি -1 এর সাথে পূর্ণ হবে আশা করে তবে এটি নয়, কেবলমাত্র প্রথম মানটি হবে এবং বাকী 0 টি এলোমেলো মানগুলির সাথে মিশ্রিত হবে।

কোড

int array[100] = {0};

ঠিক সূক্ষ্মভাবে কাজ করে এবং প্রতিটি উপাদানকে 0 তে সেট করে।

আমি এখানে কী মিস করছি ... মান শূন্য না হলে কেউ কি এটি সূচনা করতে পারে না?

এবং 2: ডিফল্ট সূচনা (উপরে হিসাবে) পুরো অ্যারের মাধ্যমে স্বাভাবিক লুপের চেয়ে দ্রুত এবং একটি মান নির্ধারণ করে বা এটি একই কাজ করে?


1
সি এবং সি ++ এর আচরণটি আলাদা। সি {0 In এ স্ট্রাক্ট ইনিশিয়ালাইজারের জন্য একটি বিশেষ কেস, তবে এএফএইকে অ্যারেগুলির জন্য নয়। ইন্ট অ্যারে [100] = {0 ar অ্যারের মতোই হওয়া উচিত [100] = {[0] = 0}, যা পার্শ্ব-প্রতিক্রিয়া হিসাবে অন্যান্য সমস্ত উপাদানকে শূন্য করবে। এসি সংকলকটি উপরে বর্ণিত হিসাবে আপনার আচরণ করা উচিত নয়, পরিবর্তে int অ্যারে [100] = {- 1 the প্রথম উপাদানটি -1 এবং বাকী 0-তে নির্ধারণ করা উচিত (শব্দহীন)। সিতে যদি আপনার স্ট্রাক্ট এক্স অ্যারে [100] থাকে তবে, আরম্ভকারী হিসাবে = {0 using ব্যবহার করা বৈধ নয়। আপনি {{0} use ব্যবহার করতে পারেন যা প্রথম উপাদানটি আরম্ভ করবে এবং অন্য সকলকে শূন্য করবে, বেশিরভাগ ক্ষেত্রে একই জিনিস হবে।
ফ্রেডরিক উইদলুন্ড

1
@ ফ্রেড্রিক উইডলুন্ড এটি উভয় ভাষায় সমান। {0}স্ট্রাক্ট বা অ্যারেগুলির জন্য কোনও বিশেষ ক্ষেত্রে নয়। নিয়মটি হ'ল কোনও প্রারম্ভিক সরঞ্জামবিহীন উপাদানগুলিকে এমনভাবে আরম্ভ করা হয় যেন তাদের কাছে 0কোনও আরম্ভকারী হিসাবে রয়েছে। যদি নেস্টেড সমষ্টি (উদাঃ struct x array[100]) থাকে তবে আরম্ভকারীগুলি "সারি-প্রধান" ক্রমে অ-সমষ্টিগুলিতে প্রয়োগ করা হয়; ব্রেসগুলি বিকল্পভাবে এটি বাদ দেওয়া যেতে পারে। struct x array[100] = { 0 }সি তে বৈধ; আর সি ++ তে বৈধ, যতক্ষণ না প্রথম সদস্য হিসাবে প্রাথমিক হিসাবে struct Xগ্রহণযোগ্য 0হয়।
এমএম

1
{ 0 }সি বিশেষ নয়, কিন্তু এটা অনেক বেশি কঠিন একটি ডাটা টাইপ যে এটা দিয়ে সক্রিয়া করা যাবে না যেহেতু কোন কনস্ট্রাকটর এবং এইভাবে বন্ধ করার কোন উপায় সংজ্ঞায়িত করতে এর 0থেকে পরোক্ষভাবে রূপান্তরিত করা হবে এবং নির্ধারিত হচ্ছে কিছু
লিউশেনকো

3
পুনরায় খোলার পক্ষে ভোট দেওয়া হয়েছে কারণ অন্য প্রশ্নটি সি সম্পর্কে রয়েছে C.
সিটিতে

1
পুনরায় খোলার পক্ষেও ভোট দিয়েছেন - সি এবং সি ++ বিভিন্ন ভাষা
পিট

উত্তর:


350

আপনি ব্যবহার করেছেন এমন সিনট্যাক্স ব্যবহার করে,

int array[100] = {-1};

সমস্ত বাদ দেওয়া উপাদানগুলিকে সেট করা থেকে যেহেতু " প্রথম উপাদানটি সেট করুন -1এবং বাকিটিতে সেট করুন" বলে ।00

C ++ এ সেগুলি সেট -1করতে আপনি কিছু std::fill_n( যেমন থেকে <algorithm>) ব্যবহার করতে পারেন :

std::fill_n(array, 100, -1);

পোর্টেবল সি-তে আপনাকে নিজের লুপটি রোল করতে হবে। সংকলক-এক্সটেনশন রয়েছে বা আপনি গ্রহণযোগ্য যদি শর্টকাট হিসাবে বাস্তবায়ন-সংজ্ঞায়িত আচরণের উপর নির্ভর করতে পারেন।


14
এটি ডিফল্ট মানগুলি "সহজেই" কীভাবে পূরণ করতে হয় সে সম্পর্কে একটি পরোক্ষ প্রশ্নের উত্তর দেয়। ধন্যবাদ.
মিলান

7
@ চেসোফনার্ড: সঠিকভাবে নয়, #include <algorithm>সঠিক শিরোনাম, <vector>এটি পরোক্ষভাবে অন্তর্ভুক্ত করতে পারে বা নাও পারে, এটি আপনার বাস্তবায়নের উপর নির্ভর করবে।
ইভান তেরান

2
রানটাইম চলাকালীন আপনাকে অ্যারে শুরু করার উপায় নিতে হবে না। যদি আপনার সত্যিকার অর্থেই স্ট্যাটিকালিটি হওয়ার দরকার হয়, তবে এর পছন্দসই অনুক্রমটি তৈরি করতে intএবং অ্যারের প্রারম্ভকালে এটি প্রসারিত করার জন্য বৈকল্পিক টেম্পলেট এবং ভেরিয়াদিক ক্রমগুলি ব্যবহার করা সম্ভব ।
শুক্র-পয়েন্টার

2
@ অনারোকস, fill_nপুরো 2D অ্যারে পূরণের জন্য কোনও একক কল ব্যবহার করার সঠিক কোনও উপায় নেই । অন্যটি পূরণ করার সময় আপনাকে একটি মাত্রা জুড়ে লুপ করতে হবে।
ইভান তেরান

7
এটি অন্য কিছু প্রশ্নের উত্তর। std::fill_nআরম্ভ নয়।
বেন ভয়েগট

133

জিসিসি সংকলকটিতে একটি এক্সটেনশন রয়েছে যা সিনট্যাক্সের অনুমতি দেয়:

int array[100] = { [0 ... 99] = -1 };

এটি সমস্ত উপাদানকে -1 এ সেট করবে।

এটি "মনোনীত প্রারম্ভিক" হিসাবে পরিচিত, আরও তথ্যের জন্য এখানে দেখুন ।

নোট করুন এটি gcc c ++ সংকলকের জন্য কার্যকর করা হয়নি।


2
অসাধারণ. এই সিনট্যাক্সটি ঝাঁকুনিতেও কাজ করে বলে মনে হয় (সুতরাং এটি আইওএস / ম্যাক ওএস এক্সে ব্যবহার করা যেতে পারে)।
জোসেফ এইচ

31

আপনি যে পৃষ্ঠায় লিঙ্ক করেছেন সেটি ইতিমধ্যে প্রথম অংশটির উত্তর দিয়েছে:

যদি একটি সুস্পষ্ট অ্যারের আকার নির্দিষ্ট করা থাকে তবে একটি সংক্ষিপ্ত সূচনা তালিকা নির্দিষ্ট করা থাকে, অনির্দিষ্ট উপাদান শূন্যে সেট করা আছে।

সম্পূর্ণ অ্যারিকে কিছু শূন্য-মান থেকে আরম্ভ করার কোনও অন্তর্নির্মিত উপায় নেই।

যার জন্য দ্রুত, সাধারণ নিয়ম প্রয়োগ হয়: "যে পদ্ধতিটি সংকলককে সর্বাধিক স্বাধীনতা দেয় তা সম্ভবত দ্রুত" faster

int array[100] = {0};

কম্পাইলারকে কেবল "এই 100 টি ints শূন্যে সেট করুন" বলে, যা সংকলকটি নিখরচায় অনুকূলিত করতে পারে।

for (int i = 0; i < 100; ++i){
  array[i] = 0;
}

আরও অনেক নির্দিষ্ট। এটি সংকলকটিকে একটি পুনরাবৃত্তি পরিবর্তনশীল তৈরি iকরতে বলে, এটি এটির ক্রমটি জানিয়ে দেয় যাতে উপাদানগুলি আরম্ভ করা উচিত, ইত্যাদি। অবশ্যই, সংকলকটি সম্ভবত এটিকে অপ্টিমাইজ করবে, তবে মূল কথাটি হ'ল এখানে আপনি সমস্যাটিকে অবিচ্ছিন্ন করছেন, সংকলককে একই ফলাফল পেতে আরও কঠোর পরিশ্রম করতে বাধ্য করছেন।

শেষ অবধি, আপনি যদি অ্যারেটিকে শূন্য-না মানতে সেট করতে চান তবে আপনার (সি ++ এ অন্তত) ব্যবহার করা উচিত std::fill:

std::fill(array, array+100, 42); // sets every value in the array to 42

আবারও আপনি অ্যারে দিয়ে একই কাজ করতে পারেন তবে এটি আরও সংক্ষিপ্ত এবং সংকলকটিকে আরও স্বাধীনতা দেয়। আপনি কেবল বলছেন যে আপনি 42 টি মানটি দিয়ে পুরো অ্যারেটি পূর্ণ করতে চান। এটি কোন ক্রম বা অন্য কিছু হতে হবে সে সম্পর্কে আপনি কিছু বলেন না।


5
ভাল উত্তর. নোট করুন যে সি ++ এ (সি তে নয়) আপনি ইনট অ্যারে করতে পারেন [100] = {}; এবং
সংকলকটিকে

1
সম্মত, দুর্দান্ত উত্তর। তবে একটি নির্দিষ্ট আকারের অ্যারের জন্য এটি স্ট্যান্ড :: ফিল_এন :- পি ব্যবহার করবে।
ইভান তেরান

12

সি ++ 11 এর আরও একটি (অপূর্ণ) বিকল্প রয়েছে:

std::array<int, 100> a;
a.fill(-1);

বাstd::fill(begin(a), end(a), -1)

9

Declared With দিয়ে আপনি উপাদানগুলি ঘোষিত হওয়ার সাথে সাথে তাদের বরাদ্দ করেন; বাকি 0 দিয়ে শুরু করা হয়।

যদি = {}italোকানোর কোনও ব্যবস্থা না থাকে তবে সামগ্রীটি অপরিজ্ঞাত।


8

আপনার লিঙ্ক করা পৃষ্ঠাটি

যদি একটি সুস্পষ্ট অ্যারের আকার নির্দিষ্ট করা থাকে তবে একটি সংক্ষিপ্ত সূচনা তালিকা নির্দিষ্ট করা থাকে, অনির্দিষ্ট উপাদান শূন্যে সেট করা আছে।

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


2
মেমকিটি খুব ভাল ধারণা নয়, যেহেতু এটি সরাসরি গতি অনুসারে মান নির্ধারণের সাথে তুলনীয় হবে।
ইভান তেরান

1
আমি অনুলিপি এবং কনস্টের অ্যারেটির প্রয়োজনীয়তা দেখতে পাচ্ছি না: কেন প্রাক-ভরাট মানগুলির সাথে প্রথম স্থানে পরিবর্তনকারী অ্যারে তৈরি করবেন না?
জোহানেস স্কাউব -

গতির ব্যাখ্যার জন্য ধন্যবাদ এবং কীভাবে এটি করা যায় যদি গতি একটি বড় অ্যারে আকারের সমস্যা (যা আমার ক্ষেত্রে হয়)
মিলন

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

@ লিটব, @ ইভান: উদাহরণস্বরূপ, সিসিপি অপ্টিমাইজেশন সক্ষম থাকা সত্ত্বেও গতিশীল সূচনা (প্রচুর মুভ) উত্পন্ন করে। জন্য বড় অ্যারে এবং টাইট কর্মক্ষমতা প্রয়োজনীয়তা, আপনি কম্পাইল সময়ে Init কাজ করতে চান। একা একা প্রচুর প্লেইন মুভের চেয়ে মেমকিপি সম্ভবত বড় কপির জন্য আরও ভাল optim
লাল্টো

4

অ্যারেটিকে একটি সাধারণ মান হিসাবে আরম্ভ করার অন্য উপায়টি হ'ল সংজ্ঞায়িত সংখ্যায় আসলে উপাদানগুলির তালিকা তৈরি করা:

#define DUP1( X ) ( X )
#define DUP2( X ) DUP1( X ), ( X )
#define DUP3( X ) DUP2( X ), ( X )
#define DUP4( X ) DUP3( X ), ( X )
#define DUP5( X ) DUP4( X ), ( X )
.
.
#define DUP100( X ) DUP99( X ), ( X )

#define DUPx( X, N ) DUP##N( X )
#define DUP( X, N ) DUPx( X, N )

একটি সাধারণ মানের সাথে একটি অ্যারে শুরু করা সহজেই করা যেতে পারে:

#define LIST_MAX 6
static unsigned char List[ LIST_MAX ]= { DUP( 123, LIST_MAX ) };

দ্রষ্টব্য: DUP এর পরামিতিগুলিতে ম্যাক্রো প্রতিস্থাপন সক্ষম করতে DUPx প্রবর্তিত


3

একক বাইট উপাদানগুলির একটি অ্যারের ক্ষেত্রে, আপনি সমস্ত উপাদানকে একই মানতে সেট করতে মেমসেট ব্যবহার করতে পারেন।

এখানে একটি উদাহরণ আছে


3

ব্যবহার করে std::array, আমরা সি ++ 14 এ মোটামুটি সোজা উপায়ে এটি করতে পারি। কেবল সি ++ 11 এ করা সম্ভব, তবে কিছুটা জটিল।

আমাদের ইন্টারফেসটি একটি সংকলন-সময় আকার এবং একটি ডিফল্ট মান।

template<typename T>
constexpr auto make_array_n(std::integral_constant<std::size_t, 0>, T &&) {
    return std::array<std::decay_t<T>, 0>{};
}

template<std::size_t size, typename T>
constexpr auto make_array_n(std::integral_constant<std::size_t, size>, T && value) {
    return detail::make_array_n_impl<size>(std::forward<T>(value), std::make_index_sequence<size - 1>{});
}


template<std::size_t size, typename T>
constexpr auto make_array_n(T && value) {
    return make_array_n(std::integral_constant<std::size_t, size>{}, std::forward<T>(value));
}

তৃতীয় ফাংশনটি মূলত সুবিধার জন্য, সুতরাং ব্যবহারকারীর নিজের তৈরি করতে হবে না std::integral_constant<std::size_t, size>, কারণ এটি একটি সুন্দর শব্দযুক্ত নির্মাণ। আসল কাজ প্রথম দুটি ফাংশনগুলির মধ্যে একটি দ্বারা সম্পন্ন হয়।

প্রথম ওভারলোডটি বেশ সোজা: এটি std::arrayআকারের 0 টি নির্মাণ করে There এখানে কোনও অনুলিপি প্রয়োজন নেই, আমরা কেবল এটি নির্মাণ করি।

দ্বিতীয় ওভারলোডটি কিছুটা কৌতুকপূর্ণ। এটি উত্স হিসাবে যে মূল্যটি পেয়েছে তা এগিয়ে নিয়ে যায় এবং এটি একটি উদাহরণও তৈরি করে make_index_sequenceএবং কেবল কিছু অন্যান্য বাস্তবায়ন ফাংশনকে কল করে। এই ফাংশনটি দেখতে কেমন?

namespace detail {

template<std::size_t size, typename T, std::size_t... indexes>
constexpr auto make_array_n_impl(T && value, std::index_sequence<indexes...>) {
    // Use the comma operator to expand the variadic pack
    // Move the last element in if possible. Order of evaluation is well-defined
    // for aggregate initialization, so there is no risk of copy-after-move
    return std::array<std::decay_t<T>, size>{ (static_cast<void>(indexes), value)..., std::forward<T>(value) };
}

}   // namespace detail

এটি যে আকারে আমরা উত্তীর্ণ হয়েছিল তা অনুলিপি করে প্রথম আকার - 1 টি আর্গুমেন্ট তৈরি করে Here এখানে, আমরা আমাদের ভ্যারিয়েডিক প্যারামিটার প্যাক সূচকগুলি কেবল কিছু প্রসারিত করার জন্য ব্যবহার করি। সেই প্যাকটিতে আকার - 1 টি এন্ট্রি রয়েছে (যেমনটি আমরা নির্মাণের ক্ষেত্রে উল্লেখ করেছি make_index_sequence), এবং তাদের 0, 1, 2, 3, ..., আকার - 2 এর মান রয়েছে তবে যাইহোক, আমরা মানগুলি (যত্নশীল) করি না ( সুতরাং যেকোন সংকলক সতর্কতা নিঃশব্দ করার জন্য আমরা এটি বাতিল করে দেব। প্যারামিটার প্যাকের সম্প্রসারণ আমাদের কোডটিকে এরকম কিছুতে প্রসারিত করে (আকার ধরে == 4):

return std::array<std::decay_t<T>, 4>{ (static_cast<void>(0), value), (static_cast<void>(1), value), (static_cast<void>(2), value), std::forward<T>(value) };

বৈকল্পিক প্যাকের প্রসারণটি ...আমরা যা চাই তা প্রসারিত করে তা নিশ্চিত করতে এবং আমরা কমা অপারেটরটি ব্যবহার করছি তা নিশ্চিত করার জন্য আমরা সেই বন্ধনীগুলি ব্যবহার করি। প্রথম বন্ধনী ব্যতীত, দেখে মনে হবে যে আমরা আমাদের অ্যারে প্রারম্ভিককরণের দিকে একগুচ্ছ যুক্তি দিয়ে যাচ্ছি, তবে সত্যই, আমরা সূচকটি মূল্যায়ন করছি, এটিকে শূন্য করে ফেলছি, সেই শূন্য ফলাফলটিকে অগ্রাহ্য করে, এবং তারপরে মানটি যা অ্যারেতে অনুলিপি করা হয়েছে ।

চূড়ান্ত যুক্তি, আমরা যাকে ডাকি std::forward, এটি একটি সামান্য অপ্টিমাইজেশন। যদি কেউ অস্থায়ী স্ট্যান্ড :: স্ট্রিংয়ে পাস করে এবং "এইগুলির মধ্যে 5 টির একটি অ্যারে তৈরি করুন" বলে, আমরা 5 টি অনুলির পরিবর্তে 4 টি অনুলিপি এবং 1 পদক্ষেপ নিতে চাই। std::forwardনিশ্চিত করে যে আমরা এই কাজ।

শিরোনাম এবং কিছু ইউনিট পরীক্ষা সহ পুরো কোড:

#include <array>
#include <type_traits>
#include <utility>

namespace detail {

template<std::size_t size, typename T, std::size_t... indexes>
constexpr auto make_array_n_impl(T && value, std::index_sequence<indexes...>) {
    // Use the comma operator to expand the variadic pack
    // Move the last element in if possible. Order of evaluation is well-defined
    // for aggregate initialization, so there is no risk of copy-after-move
    return std::array<std::decay_t<T>, size>{ (static_cast<void>(indexes), value)..., std::forward<T>(value) };
}

}   // namespace detail

template<typename T>
constexpr auto make_array_n(std::integral_constant<std::size_t, 0>, T &&) {
    return std::array<std::decay_t<T>, 0>{};
}

template<std::size_t size, typename T>
constexpr auto make_array_n(std::integral_constant<std::size_t, size>, T && value) {
    return detail::make_array_n_impl<size>(std::forward<T>(value), std::make_index_sequence<size - 1>{});
}

template<std::size_t size, typename T>
constexpr auto make_array_n(T && value) {
    return make_array_n(std::integral_constant<std::size_t, size>{}, std::forward<T>(value));
}



struct non_copyable {
    constexpr non_copyable() = default;
    constexpr non_copyable(non_copyable const &) = delete;
    constexpr non_copyable(non_copyable &&) = default;
};

int main() {
    constexpr auto array_n = make_array_n<6>(5);
    static_assert(std::is_same<std::decay_t<decltype(array_n)>::value_type, int>::value, "Incorrect type from make_array_n.");
    static_assert(array_n.size() == 6, "Incorrect size from make_array_n.");
    static_assert(array_n[3] == 5, "Incorrect values from make_array_n.");

    constexpr auto array_non_copyable = make_array_n<1>(non_copyable{});
    static_assert(array_non_copyable.size() == 1, "Incorrect array size of 1 for move-only types.");

    constexpr auto array_empty = make_array_n<0>(2);
    static_assert(array_empty.empty(), "Incorrect array size for empty array.");

    constexpr auto array_non_copyable_empty = make_array_n<0>(non_copyable{});
    static_assert(array_non_copyable_empty.empty(), "Incorrect array size for empty array of move-only.");
}

আপনার non_copyableধরণটি আসলে মাধ্যমে অনুলিপিযোগ্য operator=
হার্টজ

আমি মনে করি non_copy_constructibleঅবজেক্টটির আরও সঠিক নাম হবে। তবে এই কোডটিতে কোথাও কোনও অ্যাসাইনমেন্ট নেই, সুতরাং এই উদাহরণের জন্য এটি কোনও বিষয় নয়।
ডেভিড স্টোন

1

1) আপনি যখন ইনিশিয়ালাইজার ব্যবহার করেন তখন স্ট্রাক্ট বা এর মতো অ্যারের জন্য, অনির্ধারিত মানগুলি মূলত ডিফল্ট নির্মিত হয়। ইনটসের মতো আদিম ধরণের ক্ষেত্রে, এর অর্থ তারা শূন্য হবে। নোট করুন যে এটি পুনরাবৃত্তভাবে প্রযোজ্য: আপনার অ্যারে সম্বলিত স্ট্রাকের একটি অ্যারে থাকতে পারে এবং আপনি যদি প্রথম কাঠামোর প্রথম ক্ষেত্র নির্দিষ্ট করে থাকেন, তবে সমস্ত বাকী শূন্য এবং ডিফল্ট কনস্ট্রাক্টর দিয়ে শুরু করা হবে।

2) সংকলক সম্ভবত প্রাথমিকভাবে কোড উত্পন্ন করবে যা কমপক্ষে নিজের হাতে যতটা করতে পারে তত ভাল। আমি যখন সম্ভব তখন সংকলকটি আমার জন্য আরম্ভ করতে দেওয়া পছন্দ করে।


1) এখানে POD এর ডিফল্ট সূচনা হচ্ছে না। সংকলক তালিকাটি ব্যবহার করে সংকলন করার সময় মানগুলি তৈরি করবে এবং সেগুলি সমাবেশের একটি বিশেষ বিভাগে রাখবে যা কেবলমাত্র প্রোগ্রামের সূচনা অংশ হিসাবে কোডের মতো লোড করা হয়। সুতরাং রানটাইমটিতে ব্যয় শূন্য।
মার্টিন ইয়র্ক

1
দেখছি না সে কোথায় ভুল? int a [100] = {} অবশ্যই সমস্ত 0 টিতে প্রাথমিকভাবে শুরু হয়েছে, যেখানে এটি উপস্থিত রয়েছে তা উপেক্ষা করে স্ট্রাক্ট {int a; } খ [100] = {}; এটাও. "অপরিহার্যভাবে ডিফল্ট নির্মিত" => "মান নির্মিত", তবে। তবে এটি ইনটস, পিওডিএস বা ব্যবহারকারী ঘোষিত সিটারগুলির সাথে প্রকারের ক্ষেত্রে গুরুত্বপূর্ণ নয়। এটি কেবল নন-পডের জন্যই প্রযোজ্য কেবল ব্যবহারকারীরা ঘোষণা না করেই, আমি জানি। তবে আমি এই কারণে একটি নিচে (!) ভোট দিতে চাই না। যাইহোক, আপনার এটি আবার 0 করার জন্য +1 :)
জোহানেস স্কাউব - লিটব

@ ইভান: "যখন আপনি একটি প্রাথমিককরণ ব্যবহার করেন ..." দিয়ে আমি আমার বক্তব্যকে যোগ্য করে তুলেছিলাম আমি অবিচ্ছিন্ন মানগুলির উল্লেখ করছি না। @ মার্টিন: এটি ধ্রুবক, স্ট্যাটিক বা গ্লোবাল ডেটার জন্য কাজ করতে পারে। তবে আমি দেখতে পাচ্ছি না যে এটি কীভাবে কাজ করবে: int পরীক্ষা () i int i [10] = {0}; int v = i [0]; আমি [0] = 5; প্রত্যাবর্তন v; Each কম্পাইলারটি প্রতিবার আপনি পরীক্ষার () পরীক্ষা করার সময় শূন্য করতে i [] শুরুর দিকে আরও ভালভাবে তৈরি করা উচিত।
বুজুম

এটি স্ট্যাটিক ডেটা বিভাগে ডেটা স্থাপন করতে পারে এবং "i" এটি উল্লেখ করতে পারে :)
জোহানেস স্কাউব - লিটব

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

1

সি ++ এ, মেটা প্রোগ্রামিং এবং ভেরিয়াদিক টেম্পলেট ব্যবহার করাও সম্ভব। নিম্নলিখিত পোস্টটি এটি কীভাবে করবেন তা দেখায়: প্রোগ্রামিয়ালি সি ++ এ সংকলনের সময় স্থির অ্যারেগুলি তৈরি করুন


0

সি ++ প্রোগ্রামিং ল্যাঙ্গুয়েজ ভি 4-তে স্ট্রোস্ট্রপ বিল্টিন অ্যারেতে ভেক্টর বা ভ্যালারি ব্যবহার করার পরামর্শ দেয়। ভ্যালারারের সাথে, আপনি যখন এগুলি তৈরি করেন, আপনি এগুলিকে একটি নির্দিষ্ট মান হিসাবে শুরু করতে পারেন:

valarray <int>seven7s=(7777777,7);

"7777777" দিয়ে দীর্ঘ 7 টি সদস্যকে আরম্ভ করার জন্য।

এটি একটি "সরল পুরানো সি" অ্যারের পরিবর্তে সি ++ ডেটা কাঠামো ব্যবহার করে উত্তরটি প্রয়োগের একটি সি ++ উপায় way

আমি আমার কোডটিতে সি ++ 'এসএমএস বনাম সি'জিম ব্যবহার করার চেষ্টা করার চেষ্টা হিসাবে ভ্যালারি ব্যবহার করা স্যুইচ করেছি ....


আমি দেখেছি এমন ধরণের ব্যবহারের কীভাবে এটি দ্বিতীয় দ্বিতীয় উদাহরণ ...
স্টিজি

-3

একটি আদর্শ বৈশিষ্ট্য হওয়া উচিত তবে কোনও কারণে এটি স্ট্যান্ডার্ড সি বা সি ++ এর অন্তর্ভুক্ত নয় ...

#include <stdio.h>

 __asm__
 (
"    .global _arr;      "
"    .section .data;    "
"_arr: .fill 100, 1, 2; "
 );

extern char arr[];

int main() 
{
    int i;

    for(i = 0; i < 100; ++i) {
        printf("arr[%u] = %u.\n", i, arr[i]);
    }
}

ফোর্টরানে আপনি করতে পারেন:

program main
    implicit none

    byte a(100)
    data a /100*2/
    integer i

    do i = 0, 100
        print *, a(i)
    end do
end

তবে এটিতে স্বাক্ষরবিহীন সংখ্যা নেই ...

কেন সি / সি ++ কেবল এটি প্রয়োগ করতে পারে না। আসলেই কি এত কঠিন? একই ফল অর্জনের জন্য এটি ম্যানুয়ালি লিখতে হবে এতো নির্বোধ ...

#include <stdio.h>
#include <stdint.h>

/* did I count it correctly? I'm not quite sure. */
uint8_t arr = {
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
};    

int main() 
{
    int i;

    for(i = 0; i < 100; ++i) {
        printf("arr[%u] = %u.\n", i, arr[i]);
    }
}

এটি যদি 1,000,00 বাইটের অ্যারে হত? আমার কাছে এটি লেখার জন্য আমার একটি স্ক্রিপ্ট লিখতে হবে, বা এসেম্বলি / ইত্যাদি সহ হ্যাকের অবলম্বন করা উচিত। এটা অপদার্থ.

এটি পুরোপুরি পোর্টেবল, এটি ভাষায় না থাকার কোনও কারণ নেই।

কেবল এটিকে হ্যাক করুন:

#include <stdio.h>
#include <stdint.h>

/* a byte array of 100 twos declared at compile time. */
uint8_t twos[] = {100:2};

int main()
{
    uint_fast32_t i;
    for (i = 0; i < 100; ++i) {
        printf("twos[%u] = %u.\n", i, twos[i]);
    }

    return 0;
}

এটিকে হ্যাক করার একটি উপায় হ'ল প্রিপ্রোসেসিংয়ের মাধ্যমে ... (নীচের কোডটি প্রান্তের মামলাগুলি কভার করে না, তবে কী করা যায় তা দ্রুত প্রদর্শনের জন্য লিখিত হয়েছে is)

#!/usr/bin/perl
use warnings;
use strict;

open my $inf, "<main.c";
open my $ouf, ">out.c";

my @lines = <$inf>;

foreach my $line (@lines) {
    if ($line =~ m/({(\d+):(\d+)})/) {
        printf ("$1, $2, $3");        
        my $lnew = "{" . "$3, "x($2 - 1) . $3 . "}";
        $line =~ s/{(\d+:\d+)}/$lnew/;
        printf $ouf $line;
    } else {
        printf $ouf $line;
    }
}

close($ouf);
close($inf);

আপনি একটি লুপে মুদ্রণ করছেন, আপনি কেন একটি লুপে বরাদ্দ করতে পারবেন না?
অভিনব গৌনিয়াল

1
একটি লুপের ভিতরে বরাদ্দকরণ রানটাইম ওভারহেডকে অন্তর্ভুক্ত করে; যদিও বাফারকে হার্ডকডিংটি নিখরচায় কারণ বাফারটি ইতিমধ্যে বাইনারিতে এমবেড করা আছে, সুতরাং প্রোগ্রামটি প্রতিটি সময় সঞ্চালন করে স্ক্র্যাচ থেকে অ্যারে তৈরি করতে সময় নষ্ট করে না। আপনি ঠিক বলেছেন যে একটি লুপে মুদ্রণ সামগ্রিকভাবে একটি ভাল ধারণা নয় তবে লুপের অভ্যন্তরে সংযোজন করা এবং তারপরে একবার মুদ্রণ করা ভাল, যেহেতু প্রতিটি মুদ্রণ কলটিতে একটি সিস্টেম কল প্রয়োজন হয়, তবে অ্যাপ্লিকেশনটির হিপ / স্ট্যাক ব্যবহার করে স্ট্রিং কনটেন্টেশন দেয় না। যেহেতু এই ধরণের প্রোগ্রামের আকারটি একটি মজাদার নয়, রানাইটাইম নয়, সংকলনের সময় এই অ্যারেটি তৈরি করা ভাল।
দিমিত্রি

"একটি লুপের ভিতরে নির্ধারিত হওয়া রানটাইম ওভারহেডকে অন্তর্ভুক্ত করে" - আপনি অপটিমাইজারটিকে গুরুতরভাবে মূল্যায়ন করবেন না।
আসু

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