সি অ্যারেগুলির দৈর্ঘ্য 0 কেন হতে পারে না?


13

সি 11 স্ট্যান্ডার্ড বলছে যে অ্যারেগুলির আকার এবং ভেরিয়েবল উভয় দৈর্ঘ্য "শূন্যের চেয়ে বড় হবে" " 0 দৈর্ঘ্যের অনুমতি না দেওয়ার যৌক্তিকতা কী?

বিশেষত পরিবর্তনশীল দৈর্ঘ্যের অ্যারেগুলির জন্য এটি একবার এবং কিছু সময় শূন্যের আকার ধারণ করার জন্য সঠিক ধারণা দেয় sense এটি স্ট্যাটিক অ্যারেগুলির জন্যও কার্যকর যখন তাদের আকার ম্যাক্রো বা বিল্ড কনফিগারেশন বিকল্প থেকে হয়।

মজার বিষয় হ'ল জিসিসি (এবং ঝনঝন) এমন এক্সটেনশানগুলি সরবরাহ করে যা শূন্য দৈর্ঘ্যের অ্যারেগুলিকে অনুমতি দেয়। জাভা দৈর্ঘ্যের শূন্যের অ্যারেগুলিকেও মঞ্জুরি দেয়।


7
stackoverflow.com/q/8625572 ... "শূন্য দৈর্ঘ্যের একটি অ্যারে জটিল এবং বিভ্রান্তিকর হবে যে প্রতিটি বস্তুর একটি পৃথক ঠিকানা রয়েছে সেই প্রয়োজনীয়তার সাথে মিলিয়ে তুলতে"।
রবার্ট হার্ভে

3
@ রবার্টহারভে: প্রদত্ত struct { int p[1],q[1]; } foo; int *pp = p+1;, ppএকটি বৈধ পয়েন্টার হবে, তবে এর *ppকোনও অনন্য ঠিকানা থাকবে না। কেন একই যুক্তিটি শূন্য দৈর্ঘ্যের অ্যারে ধরে রাখতে পারে না? বলুন যে int q[0]; কোনও কাঠামোর মধ্যে দেওয়া হয়েছে , qএমন কোনও ঠিকানা উল্লেখ করবে যার বৈধতা p+1উপরের উদাহরণের মতো হবে ।
সুপারক্যাট

@ ডকব্রাউন সি 11 স্ট্যান্ডার্ড থেকে 6.7.6.2.5 থেকে ভিএলএর আকার নির্ধারণ করতে ব্যবহৃত অভিব্যক্তি সম্পর্কে কথা বলছেন "... প্রতিবার যখন এটি মূল্যায়ন করা হয় তখন এর মান শূন্যের চেয়ে বড় হবে" " আমি C99 সম্পর্কে জানি না (এবং এটি অদ্ভুত বলে মনে হচ্ছে যে তারা এটি পরিবর্তন করবে) তবে মনে হচ্ছে আপনার দৈর্ঘ্যের শূন্য থাকতে পারে না।
কেভিন কক্স

@ কেভিনকক্স: সি 11 স্ট্যান্ডার্ডের (বা প্রশ্নে থাকা অংশ) একটি বিনামূল্যে অনলাইন সংস্করণ পাওয়া যায়?
ডক ব্রাউন

চূড়ান্ত সংস্করণটি নিখরচায় উপলব্ধ নয় (কী লজ্জাজনক) তবে আপনি খসড়া ডাউনলোড করতে পারেন। সর্বশেষ উপলব্ধ খসড়াটি ওপেন-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
কেভিন কক্স

উত্তর:


11

আমি যে বিষয়টি বাজি রাখতে চাই তা হ'ল সি অ্যারেগুলি কেবল মেমরির একটি বরাদ্দ অংশের শুরুতে পয়েন্টার হয়। একটি 0 আকারের অর্থ হ'ল আপনার কাছে পয়েন্টার আছে ... কিছুই না? আপনার কিছুই থাকতে পারে না, তাই সেখানে কিছু স্বেচ্ছাচারী জিনিস বেছে নেওয়া উচিত ছিল। আপনি ব্যবহার করতে পারবেন না nullকারণ আপনার 0 দৈর্ঘ্যের অ্যারেগুলি নাল পয়েন্টারগুলির মতো দেখায়। এবং এই মুহূর্তে প্রতিটি পৃথক বাস্তবায়ন বিশৃঙ্খলার দিকে পরিচালিত করে বিভিন্ন স্বেচ্ছাচারী আচরণ বাছাই করতে চলেছে।



8
@ ডেলান: ঠিক আছে, আপনি যদি এটি সম্পর্কে পেডেন্টিক হতে চান তবে অ্যারে এবং পয়েন্টার গাণিতিকটি এমনভাবে সংজ্ঞায়িত করা হয় যে কোনও পয়েন্টারটি সহজেই একটি অ্যারে অ্যাক্সেস করতে বা অ্যারের অনুকরণের জন্য ব্যবহার করা যেতে পারে। অন্য কথায়, এটি পয়েন্টার পাটিগণিত এবং অ্যারে সূচক যা সি এর সমান But তবে ফলাফলটি যাইহোক একই রকম ... যদি অ্যারের দৈর্ঘ্য শূন্য হয়, আপনি এখনও কিছুই দেখান নি।
রবার্ট হার্ভে

3
@ রবার্টহারভে সব সত্য, তবে আপনার সমাপনী শব্দগুলি (এবং পূর্ববর্তী উত্তর পুরো উত্তর) কেবল এমন বিভ্রান্ত ও বিভ্রান্তির মতো বলে মনে হচ্ছে যে এই জাতীয় অ্যারে (আমি মনে করি এই উত্তরটি "মেমরির একটি বরাদ্দ অংশ" বলবে)? sizeof0, এবং কীভাবে এটি সমস্যার কারণ হতে পারে। ব্রাভিটি বা স্পষ্টতার কোনও ক্ষতি ছাড়াই সঠিক ধারণা এবং পরিভাষা ব্যবহার করে যা ব্যাখ্যা করা যায়। অ্যারে এবং পয়েন্টারগুলি মিশ্রিত করা কেবল কোনও লাভের জন্য অ্যারে = পয়েন্টারগুলির ভুল ধারণা (যা অন্যান্য প্রসঙ্গে আরও গুরুত্বপূর্ণ) ছড়িয়ে ঝুঁকিপূর্ণ।

2
" আপনি নাল ব্যবহার করতে পারবেন না, কারণ তারপরে আপনার 0 দৈর্ঘ্যের অ্যারেগুলি নাল পয়েন্টারগুলির মতো দেখায় " - আসলে ডেলফি যা করেন তা ঠিক তাই। খালি ডায়নারি এবং খালি লংস্ট্রিং প্রযুক্তিগতভাবে নাল পয়েন্টার।
জেনসজি

3
-১, আমি এখানে ডেলান দিয়ে পূর্ণ। এটি কিছুই ব্যাখ্যা করে না, বিশেষত ওপি শূন্য দৈর্ঘ্যের অ্যারের ধারণাকে সমর্থনকারী কিছু বড় সংকলক সম্পর্কে কী লিখেছিল সে প্রসঙ্গে। আমি পুরোপুরি নিশ্চিত যে শূন্য দৈর্ঘ্যের অ্যারেগুলি একটি বাস্তবায়ন-অব্যাহত উপায়ে সি তে সরবরাহ করা যেতে পারে, "বিশৃঙ্খলার দিকে পরিচালিত করে না"।
ডক ব্রাউন 13

6

আসুন দেখে নেওয়া যাক কীভাবে সাধারণত অ্যারে মেমোরিতে রাখা হয়:

         +----+
arr[0] : |    |
         +----+
arr[1] : |    |
         +----+
arr[2] : |    |
         +----+
          ...
         +----+
arr[n] : |    |
         +----+

মনে রাখবেন যে নামের নামে আলাদা কোনও বস্তু arrনেই যা প্রথম উপাদানটির ঠিকানা সঞ্চয় করে; যখন কোনও বিন্যাসে একটি অ্যারে উপস্থিত হয়, সি প্রয়োজনীয় উপাদান হিসাবে প্রথম উপাদানটির ঠিকানা গণনা করে।

সুতরাং, আসুন এই সম্পর্কে চিন্তা: 0-উপাদানের বিন্যাস হবে আর সঞ্চয়স্থান জন্য সরাইয়া সেট, অ্যারের ঠিকানা গনা কিছু নেই, যার অর্থ থেকে (অন্য উপায় করা, সেখানে শনাক্তকারীর জন্য কোন বস্তু ম্যাপিং এর)। এটি বলার মতো, "আমি একটি intপরিবর্তনশীল তৈরি করতে চাই যা কোনও স্মৃতি গ্রহণ করে না।" এটি একটি অযৌক্তিক অপারেশন।

সম্পাদন করা

জাভা অ্যারে সি এবং সি ++ অ্যারে থেকে সম্পূর্ণ আলাদা প্রাণী; এগুলি কোনও আদিম ধরণের নয়, তবে একটি রেফারেন্স টাইপ Object

সম্পাদনা 2

নীচের মন্তব্যে একটি পয়েন্ট সামনে এলো - "0 টিরও বেশি" সীমাবদ্ধতা কেবলমাত্র অ্যারেগুলিতে প্রযোজ্য যেখানে আকারটি ধ্রুবক প্রকাশের মাধ্যমে নির্দিষ্ট করা হয় ; একটি ভিএলএর 0 দৈর্ঘ্যের অনুমতি রয়েছে 0 টি-মানযুক্ত অ ধ্রুবক প্রকাশের সাথে একটি ভিএলএ ঘোষণা করা সীমাবদ্ধতা লঙ্ঘন নয়, তবে এটি অনির্ধারিত আচরণের প্ররোচনা দেয়।

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

সি 11 হিসাবে, VLAs সমর্থন করার জন্য বাস্তবায়নের প্রয়োজন হয় না এটিরও মূল্য নেই।


3
দুঃখিত, তবে আইএমএইচও আপনি টেলাস্টিনের মতো পয়েন্টটি মিস করছেন। শূন্য দৈর্ঘ্যের অ্যারেগুলি প্রচুর পরিমাণে ধারণা তৈরি করতে পারে এবং ওপি যেমন আমাদের সম্পর্কে যা বলেছিল তার মতো বিদ্যমান বাস্তবায়নগুলি দেখায় যে এটি করা যেতে পারে।
ডক ব্রাউন

@ ডকব্রাউন: প্রথমে, আমি ভাষায় ছিলাম যে কেন ভাষা স্ট্যান্ডার্ড সম্ভবত তাদের এড়িয়ে যায়। দ্বিতীয়ত, আমি যেখানে একটি 0-দৈর্ঘ্যের অ্যারেটি বোঝায় তার একটি উদাহরণ চাই, কারণ আমি সত্যিই কোনওটির কথা ভাবতে পারি না। সর্বাধিক সম্ভাব্য বাস্তবায়ন T a[0]হিসাবে হিসাবে আচরণ করা হয় T *a, কিন্তু তারপরে কেন কেবল ব্যবহার T *aকরবেন না ?
জন বোদে

দুঃখিত, তবে মানক কেন এটি নিষিদ্ধ করে তার জন্য আমি "তাত্ত্বিক যুক্তি" কিনছি না। আমার উত্তরটি পড়ুন কীভাবে ঠিকানাটি সহজেই সহজেই গণনা করা যায়। এবং আমি আপনাকে রবার্ট হারভেয়েসের লিঙ্কটি অনুসরণ করে প্রশ্নের প্রথম মন্তব্যটি এবং দ্বিতীয় উত্তরটি পড়ার পরামর্শ দিচ্ছি, এর একটি কার্যকর উদাহরণ রয়েছে।
ডক ব্রাউন

@ ডকব্রাউন: আহ। structহ্যাক। আমি এটি ব্যক্তিগতভাবে কখনও ব্যবহার করি নি; ভেরিয়েবল-আকারের structধরণের প্রয়োজন এমন কোনও সমস্যায় কখনও কাজ করেননি ।
জন বোদে

2
এবং C৯৯৯ এর পর থেকে এএফাইককে ভুলে যাবেন না, সি পরিবর্তনশীল-দৈর্ঘ্যের অ্যারেগুলিকে অনুমতি দেয়। এবং যখন অ্যারের আকারটি একটি প্যারামিটার হয় তবে 0 এর মানকে বিশেষ ক্ষেত্রে বিবেচনা না করে প্রচুর প্রোগ্রাম সহজতর করতে পারে।
ডক ব্রাউন

2

আপনি সাধারণত আপনার শূন্য (প্রকৃত পরিবর্তনশীল) আকারের অ্যারেটি রান সময় সময়ে এর আকার জানতে চান। তারপরে এটি প্যাক করুন structএবং নমনীয় অ্যারে সদস্যগুলি ব্যবহার করুন , যেমন:

struct my_st {
   unsigned len;
   double flexarray[]; // of size len
};

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

অবশ্যই আপনি বরাদ্দ হবে:

 unsigned len = some_length_computation();
 struct my_st*p = malloc(sizeof(struct my_st)+len*sizeof(double));
 if (!p) { perror("malloc my_st"); exit(EXIT_FAILURE); };
 p->len = len;
 for (unsigned ix=0; ix<len; ix++)
    p->flexarray[ix] = log(3.0+(double)ix);

আফাইক, C99 এ এটি ইতিমধ্যে সম্ভব ছিল এবং এটি খুব দরকারী।

বিটিডাব্লু, নমনীয় অ্যারে সদস্যদের সি ++ তে বিদ্যমান নেই (কারণ কখন এবং কীভাবে তাদের নির্মাণ ও ধ্বংস করা উচিত তা নির্ধারণ করা কঠিন হবে) difficult তবে ভবিষ্যতের স্ট্যান্ড :: ডিনাররে দেখুন


আপনি জানেন, এগুলি কেবল তুচ্ছ ধরনের হতে পারে এবং কোনও অসুবিধা হবে না।
Deduplicator

2

যদি type name[count]কোনও ফাংশনে এক্সপ্রেশন লেখা থাকে তবে আপনি সি সংকলককে স্ট্যাক ফ্রেম sizeof(type)*countবাইটে বরাদ্দ করতে এবং অ্যারের মধ্যে প্রথম উপাদানটির ঠিকানা গণনা করতে বলুন ।

যদি অভিব্যক্তিটি type name[count]সমস্ত ফাংশনগুলির বাইরে লিখিত হয় এবং সংজ্ঞাগুলি নির্দেশ করে তবে আপনি সি কম্পাইলারকে ডেটা সেগমেন্ট sizeof(type)*countবাইটে বরাদ্দ করতে এবং অ্যারের মধ্যে প্রথম উপাদানটির ঠিকানা গণনা করতে বলে।

nameআসলে ধ্রুবক বস্তু যা অ্যারের প্রথম উপাদানটির ঠিকানা সঞ্চয় করে এবং প্রতিটি বস্তু যা কিছু মেমরির ঠিকানা সঞ্চয় করে তাকে পয়েন্টার বলা হয়, সুতরাং এটি কারণ যা আপনি nameঅ্যারের চেয়ে পয়েন্টার হিসাবে বিবেচনা করেন। নোট করুন যে সি তে অ্যারেগুলি কেবল পয়েন্টারগুলির মাধ্যমেই অ্যাক্সেস করা যায়।

যদি countকোনও ধ্রুবক অভিব্যক্তি যা শূন্যকে মূল্যায়ণ করে তবে আপনি সি সংকলককে স্ট্যাক ফ্রেম বা ডেটা বিভাগে শূন্য বাইট বরাদ্দ করতে এবং অ্যারের মধ্যে প্রথম উপাদানটির ঠিকানা ফেরত দিতে বলুন, তবে এটি করার ক্ষেত্রে সমস্যাটি হ'ল প্রথম উপাদানটি শূন্য দৈর্ঘ্যের অ্যারের উপস্থিতি নেই এবং আপনি অস্তিত্ব নেই এমন কোনও ঠিকানার গণনা করতে পারবেন না।

এটি যৌক্তিক যে উপাদান নং। দৈর্ঘ্যের অ্যারে count+1বিদ্যমান নেই count, সুতরাং এই কারণেই সি সংকলকটি কোনও ফাংশনের ভিতরে এবং বাইরে ভেরিয়েবল হিসাবে শূন্য দৈর্ঘ্যের অ্যারে সংজ্ঞায়িত করতে নিষেধ করে, কারণ nameতখনকার বিষয়বস্তু কী ? nameঠিক ঠিক ঠিকানা কি ?

যদি pপয়েন্টার হয় তবে এক্সপ্রেশনটি p[n]সমান*(p + n)

যেখানে ডান দিকের অ্যাসিরিস্ক * পয়েন্টারের ডেরিফারেন্স অপারেশন, যার অর্থ দ্বারা চিহ্নিত p + nমেমোরিটি অ্যাক্সেস করা বা মেমরিটি অ্যাক্সেস করতে পারে যার ঠিকানা সঞ্চিত আছে p + n, যেখানে p + nপয়েন্টার এক্সপ্রেশন রয়েছে, এটি ঠিকানাটি নিয়ে যায় pএবং এই ঠিকানায় সংখ্যাকে nগুণিত করে পয়েন্টারের ধরণের আকার p

একটি ঠিকানা এবং একটি নম্বর যুক্ত করা সম্ভব?

হ্যাঁ এটি সম্ভব, কারণ ঠিকানাটি স্বাক্ষরযুক্ত পূর্ণসংখ্যাটি হেক্সাডেসিমাল স্বরলিপিতে সাধারণত উপস্থাপিত হয়।


অনেক সংকলক স্ট্যান্ডার্ড এটি নিষিদ্ধ করার আগে শূন্য আকারের অ্যারে ঘোষণার মঞ্জুরি দেয় এবং অনেকগুলি এই ধরণের ঘোষণাকে এক্সটেনশন হিসাবে অনুমতি দেয়। এই জাতীয় ঘোষণার ফলে কোনও সমস্যা হবে না যদি কেউ স্বীকৃতি দেয় যে আকারের কোনও অবজেক্টের Nসাথে N+1সম্পর্কিত ঠিকানা রয়েছে, Nযার মধ্যে প্রথমটি অনন্য বাইটগুলি সনাক্ত করে এবং সর্বশেষে Nপ্রতিটি বিন্দু those বাইটগুলির মধ্যে একটিতে গিয়েছে। এই জাতীয় সংজ্ঞাটি হ্রাস পাওয়ার ক্ষেত্রেও ঠিক কাজ করবে যেখানে N0 হয়
সুপারক্যাট

1

আপনি যদি কোনও মেমরি ঠিকানার পয়েন্টার চান তবে একটিটি ঘোষণা করুন। একটি অ্যারে আসলে আপনার সংরক্ষিত মেমরির একটি অংশকে নির্দেশ করে। ক্রিয়াকলাপগুলিতে পাস করার সময় অ্যারেগুলি পয়েন্টারে ক্ষয় হয়, তবে তারা যে স্মৃতিটি দেখিয়ে থাকে তা যদি গাদা থাকে তবে কোনও সমস্যা নেই। আকার শূন্যের অ্যারে ঘোষণা করার কোনও কারণ নেই।


2
সাধারণত আপনি সরাসরি এটি করেননি তবে ম্যাক্রোর ফলস্বরূপ বা গতিশীল ডেটা সহ একটি পরিবর্তনশীল দৈর্ঘ্যের অ্যারে ঘোষণা করার সময়।
কেভিন কক্স

একটি অ্যারে কখনও নির্দেশ করে না। এতে পয়েন্টার থাকতে পারে এবং বেশিরভাগ প্রসঙ্গে আপনি আসলে প্রথম উপাদানটির জন্য একটি পয়েন্টার ব্যবহার করেন তবে এটি ভিন্ন গল্প।
উত্সাহক

1
অ্যারের নাম অ্যারেতে থাকা মেমরির একটি ধ্রুবক পয়েন্টার।
ncmathsadist

1
না, অ্যারের নাম করতে decays সবচেয়ে প্রেক্ষিতে প্রথম উপাদান একটি পয়েন্টার। পার্থক্য প্রায়শই গুরুত্বপূর্ণ।
উত্সর্গকারীর

1

আসল সি 89 এর দিন থেকেই, যখন কোনও সি স্ট্যান্ডার্ড নির্দিষ্ট করে দেয় যে কোনও কিছুর অপরিজ্ঞাত আচরণ রয়েছে, তার অর্থ "নির্দিষ্ট টার্গেট প্ল্যাটফর্মের উপর ভিত্তি করে যে উদ্দেশ্যে করা উচিত তার লক্ষ্যমাত্রার জন্য সবচেয়ে উপযুক্ত" Do স্ট্যান্ডার্ডের লেখকরা কোন আচরণের জন্য কোন বিশেষ উদ্দেশ্যে সবচেয়ে উপযুক্ত হতে পারে তা অনুমান করার চেষ্টা করতে চাননি। ভিএলএ এক্সটেনশনগুলির সাথে বিদ্যমান সি 89 বাস্তবায়নগুলি শূন্যের আকার দেওয়ার সময় আচরণগুলি আলাদা, তবে যৌক্তিক হতে পারে (উদাহরণস্বরূপ, কেউ কেউ এনআরএল প্রদান করে এমন একটি অ্যাড্রেস এক্সপ্রেশন হিসাবে অ্যারের সাথে আচরণ করেছেন, অন্যরা এটির ঠিকানা সমান হতে পারে এমন ঠিকানা সংজ্ঞা হিসাবে আচরণ করছেন অন্য একটি নির্বিচারে পরিবর্তনশীল, তবে নিরাপদে ফাঁদে না এনে শূন্যে যুক্ত করা যেতে পারে)। কোনও কোড যদি এইরকম ভিন্ন আচরণের উপর নির্ভর করে থাকতে পারে তবে স্ট্যান্ডার্ডের লেখকরা চাইতেন না '

বাস্তবায়নগুলি কী কী হতে পারে তা অনুমান করার চেষ্টা করার পরিবর্তে বা কোনও আচরণকে যে কোনওর চেয়ে শ্রেষ্ঠ হিসাবে বিবেচনা করা উচিত বলে পরামর্শ দেওয়ার পরিবর্তে, স্ট্যান্ডার্ডের লেখকরা কার্যকরভাবে উপযুক্ত হিসাবে বিবেচিত মামলাটি পরিচালনার ক্ষেত্রে রায় প্রয়োগের অনুমতি দিয়েছিলেন allowed পর্দার পিছনে malloc () ব্যবহার করে এমন প্রয়োগগুলি অ্যারের ঠিকানাটিকে NULL হিসাবে বিবেচনা করতে পারে (যদি আকার-শূন্য ম্যালোক ফল দেয়) তবে স্ট্যাক-ঠিকানা গণনাগুলি ব্যবহার করে এমন একটি পয়েন্টার পাওয়া যায় যা কিছু অন্যান্য ভেরিয়েবলের ঠিকানার সাথে মেলে এবং অন্য কিছু বাস্তবায়নও করতে পারে অন্য জিনিস. আমি মনে করি না যে তারা আশা করেছিল যে সংকলক লেখকরা শূন্য-আকারের কর্নার কেসটি ইচ্ছাকৃতভাবে-অকেজো ফ্যাশনে আচরণ করবে their

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