নেতিবাচক অ্যারে সূচকগুলি কেন বোঝায়?


14

আমি সি প্রোগ্রামিংয়ের একটি অদ্ভুত অভিজ্ঞতা পেয়েছি। এই কোডটি বিবেচনা করুন:

int main(){
  int array1[6] = {0, 1, 2, 3, 4, 5};
  int array2[6] = {6, 7, 8, 9, 10, 11};

  printf("%d\n", array1[-1]);
  return 0;
}

আমি যখন এটি সংকলন এবং চালনা করি তখন আমি কোনও ত্রুটি বা সতর্কতা পাই না। আমার প্রভাষক যেমন বলেছিলেন, অ্যারে সূচকটি -1আরও একটি পরিবর্তনশীল অ্যাক্সেস করে। আমি এখনও বিভ্রান্ত, কেন পৃথিবীতে প্রোগ্রামিং ভাষার এই ক্ষমতা আছে? মানে, নেতিবাচক অ্যারে সূচকগুলিকে কেন অনুমতি দিন?


2
যদিও এই প্রশ্নটি সি দিয়ে কংক্রিট প্রোগ্রামিং ভাষা হিসাবে প্রেরণা পেয়েছে, আমি মনে করি এটি ধারণাগত প্রশ্ন হিসাবে বোঝা যাবে যা এখানে অনটপিক (যদি সবেমাত্র হয়)।
রাফেল

7
@ রাফেল আমি একমত নই এবং বিশ্বাস করি এটি এসও এর অন্তর্ভুক্ত হওয়া উচিত, এটি কোনওভাবেই পাঠ্যপুস্তকের অপরিজ্ঞাত আচরণ (অ্যারের বাইরে স্মৃতি রেফারেন্সিং) এবং সঠিক সংকলক পতাকাগুলি সম্পর্কে এই সম্পর্কে সতর্ক করা উচিত
রাচেট ফ্রিক

আমি @ratchetfreak এর সাথে একমত বৈধ সূচকের পরিসর [0, 5] হওয়ায় এটি একটি সংকলক ত্রুটি বলে মনে হচ্ছে। বাইরের যে কোনও কিছু অবশ্যই সংকলন / রানটাইম ত্রুটি হতে পারে। সাধারণ হিসাবে, ভেক্টরগুলি হ'ল ফাংশনগুলির বিশেষ ক্ষেত্রে যার প্রথম উপাদান সূচকটি ব্যবহারকারীর উপর নির্ভর করে। যেহেতু সি চুক্তিটি হল যে উপাদানগুলি সূচক 0 থেকে শুরু হয়, তাই এটি নেতিবাচক উপাদানগুলিতে অ্যাক্সেস করতে ত্রুটি।
Val,

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

4
@ গিলস যদি এই প্রশ্নের মূল বিষয় হয় তবে এটি অবশ্যই স্ট্যাক ওভারফ্লোতে হওয়া উচিত ছিল ।
রাফেল

উত্তর:


27

অ্যারের ইনডেক্সিং অপারেশন a[i]সি এর নিম্নলিখিত বৈশিষ্ট্যগুলি থেকে এর অর্থ অর্জন করে

  1. বাক্য গঠনটি a[i]সমান *(a + i)। সুতরাং এটি 5[a]5 তম উপাদান পেতে বলা বৈধ a

  2. পয়েন্টার-গাণিতিক বলে যে একটি পয়েন্টার pএবং একটি পূর্ণসংখ্যা দেওয়া হয় i, p + i পয়েন্টারটি বাইট pদ্বারা অগ্রসর হয়i * sizeof(*p)

  3. একটি অ্যারের নাম aখুব দ্রুত 0 এর এলিমেন্টের পয়েন্টারে রূপান্তরিত হয়a

কার্যত, অ্যারে-ইনডেক্সিং পয়েন্টার-ইনডেক্সিংয়ের একটি বিশেষ ক্ষেত্রে। যেহেতু একটি পয়েন্টার অ্যারের অভ্যন্তরের যে কোনও জায়গার দিকে ইঙ্গিত করতে পারে, তাই যেকোন স্বেচ্ছাসেবী অভিব্যক্তি যা পরীক্ষার দ্বারা ভুল p[-1]হয় না এবং তাই সংকলকরা এ জাতীয় সমস্ত অভিব্যক্তিকে ত্রুটি হিসাবে বিবেচনা করে না (করতে পারে না)।

আপনাদের উদাহরণ a[-1]যেখানে aআসলে একটি অ্যারের নাম আসলে অবৈধ। আইআইআরসি, এটি সংজ্ঞায়িত যদি অভিব্যক্তির ফলাফল হিসাবে একটি অর্থবহ পয়েন্টার মান থাকে a - 1যেখানে aএকটি অ্যারের 0 তম উপাদানটির জন্য একটি পয়েন্টার হিসাবে জানা যায়। সুতরাং, একটি চালাক সংকলক এটি সনাক্ত করতে পারে এবং এটিকে ত্রুটি হিসাবে চিহ্নিত করতে পারে। এলোমেলো স্ট্যাক স্লটে আপনাকে একটি পয়েন্টার দিয়ে পায়ে নিজেকে গুলি করতে দেওয়ার সময় অন্য সংকলকগুলি এখনও মেনে চলতে পারে।

কম্পিউটার বিজ্ঞানের উত্তরটি হ'ল:

  • সিতে []অপারেটরটি অ্যারে নয়, পয়েন্টারে সংজ্ঞায়িত করা হয়। বিশেষত, এটি পয়েন্টার পাটিগণিত এবং পয়েন্টার বিন্যাসের ক্ষেত্রে সংজ্ঞায়িত করা হয়।

  • সি-তে, একটি পয়েন্টারটি বিমূর্তভাবে (start, length, offset)শর্তযুক্ত একটি টুপল 0 <= offset <= length। পয়েন্টার গাণিতিকটি অফসেটে মূলত গাণিতিক উত্তোলন করা হয়, সতর্কতার সাথে যে অপারেশনের ফলাফল যদি পয়েন্টার শর্তটি লঙ্ঘন করে তবে এটি একটি অপরিবর্তিত মান। পয়েন্টারকে ডি-রেফারেন্স করা একটি অতিরিক্ত বাধা যুক্ত করে offset < length

  • সি এর একটি ধারণা রয়েছে undefined behaviourযার একটি সংকলক একক সংখ্যা হিসাবে এই টিপলকে দৃ concrete়ভাবে উপস্থাপন করতে দেয় এবং পয়েন্টার শর্তের কোনও লঙ্ঘন সনাক্ত করতে পারে না । বিমূর্ত শব্দার্থতাকে সন্তুষ্ট করে এমন কোনও প্রোগ্রাম কংক্রিট (ক্ষতিকারক) শব্দার্থক দিয়ে নিরাপদ থাকবে। বিমূর্ত শব্দার্থবিধি লঙ্ঘনকারী যে কোনও কিছুই মন্তব্য ছাড়াই, সংকলক দ্বারা গ্রহণযোগ্য হতে পারে এবং এটি এর সাথে যা করতে চায় তা করতে পারে।


কোনও নির্দিষ্ট প্রোগ্রামিং ভাষার আইডিসিঙ্ক্রেসিগুলির উপর নির্ভর করে কোনও নয়, দয়া করে একটি সাধারণ উত্তর দেওয়ার চেষ্টা করুন।
রাফেল

6
@ রাফেল, প্রশ্নটি সি সম্পর্কে স্পষ্টতই মনে হয়েছিল আমি মনে করি যে সি এর সংজ্ঞার মধ্যে কেন একটি সি সংকলককে আপাতদৃষ্টিতে অর্থহীন অভিব্যক্তি সংকলন করার অনুমতি দেওয়া হয়েছিল তার নির্দিষ্ট প্রশ্নে আমি সম্বোধন করেছি
হরি ২

বিশেষত সি সম্পর্কে প্রশ্নগুলি এখানে অফটোপিক; প্রশ্নে আমার মন্তব্য নোট করুন।
রাফেল

5
আমি বিশ্বাস করি যে প্রশ্নের তুলনামূলক ভাষাতত্ত্বের দিকটি এখনও কার্যকর। আমি বিশ্বাস করি যে একটি নির্দিষ্ট বাস্তবায়ন কেন নির্দিষ্ট কংক্রিট শব্দার্থবিজ্ঞানের প্রদর্শন করেছে তার একটি মোটামুটি "কম্পিউটার-বিজ্ঞান" স্বাদযুক্ত বর্ণনা দিয়েছি।
হরি

15

অ্যারেগুলি কেবল মেমরির সংলগ্ন অংশ হিসাবে নির্ধারিত হয়। একটি অ্যারে অ্যাক্সেস যেমন একটি [i] মেমরি অবস্থানের ঠিকানায় অ্যাক্সেসে রূপান্তরিত হয় (ক) + i। এই কোডটি a[-1]নিখুঁতভাবে বোধগম্য, এটি অ্যারে শুরুর আগে ঠিক ঠিকানাটি বোঝায়।

এটি পাগল বলে মনে হতে পারে তবে এর অনুমতি দেওয়ার অনেক কারণ রয়েছে:

  • আমি [থেকে] সূচকটি অ্যারের সীমানার মধ্যে কিনা তা খতিয়ে দেখা ব্যয়বহুল।
  • কিছু প্রোগ্রামিং কৌশল সত্য যা সত্য তা কাজে লাগায় a[-1]। উদাহরণস্বরূপ, যদি আমি জানি যে aএটি আসলে অ্যারের শুরু নয়, তবে অ্যারের মাঝখানে একটি পয়েন্টার, তবে a[-1]কেবল পয়েন্টারের বামদিকে অ্যারের উপাদানটি পাওয়া যায়।

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

উত্তরের জন্য ধন্যবাদ, কিন্তু আমি ধারণাটি পেলাম না। বিটিডব্লিউ আমি না বুঝে এটি আবার বারবার পড়ব .. :)
মোহাম্মদ ফাওজান

2
@ রাফেল: কোলা অবজেক্ট মডেলটির বাস্তবায়নটি ভিটিবেল সংরক্ষণ করার জন্য -1 পজিশনটি ব্যবহার করে: পিউমার্টা / সোফটওয়্যার / কোলা / আপোমোডেল 2.pdf । সুতরাং ক্ষেত্রগুলি বস্তুর ধনাত্মক অংশে সংরক্ষণ করা হয় এবং inণাত্মক মধ্যে vtable। আমি বিশদটি মনে করতে পারি না, তবে আমি মনে করি এটি ধারাবাহিকতার সাথে করা।
ডেভ ক্লার্ক

@ ডিজেরো টক্সিন: একটি অ্যারে হ'ল মেমরির কেবলমাত্র একটি অবস্থান, এর পাশের কিছু লোকেশন যা যুক্তিযুক্তভাবে অ্যারের অংশ। তবে সত্যই, একটি অ্যারে কেবল পয়েন্টার।
ডেভ ক্লার্ক

1
@ রাফেল, কিছু ক্ষেত্রে a[-1]সঠিক ধারণা দেয় , এই বিশেষ ক্ষেত্রে এটি সাধারণ অবৈধ (তবে সংকলক দ্বারা ধরা পড়ে না)a
ভোনব্রান্ড ২

4

অন্যান্য উত্তরগুলি ব্যাখ্যা করার সাথে সাথে এটি সি এর অপরিজ্ঞাত আচরণ Consider বিবেচনা করুন যে সি একটি "উচ্চ স্তরের এসেম্বারलर" হিসাবে সংজ্ঞায়িত হয়েছিল (এবং বেশিরভাগ ব্যবহৃত হয়)। সি এর ব্যবহারকারীরা এর আপত্তিহীন গতির জন্য এটিকে মূল্য দেয় এবং রানটাইম এ স্টাফ চেক করা নিছক পারফরম্যান্সের জন্য প্রশ্নটির বাইরে থাকে (বেশিরভাগ)। কিছু সি নির্মান যে চেহারা অন্যান্য ভাষা থেকে আসতেছে মানুষের জন্য অর্থহীন ভালো সি নিখুঁত জানার জন্য, a[-1]। হ্যাঁ, এটি সর্বদা অর্থপূর্ণ নয় (


1
আমি এই উত্তর পছন্দ। কেন এটি ঠিক আছে তার বাস্তব কারণ দেয় G
darxsys

3

মেমরির সরাসরি বরাদ্দ থাকা মেমরি বরাদ্দ পদ্ধতিগুলি লিখতে এমন একটি বৈশিষ্ট্য ব্যবহার করা যেতে পারে। এরকম একটি ব্যবহার হ'ল দুটি ব্লক একত্রিত করা যায় কিনা তা নির্ধারণ করতে নেতিবাচক অ্যারে সূচক ব্যবহার করে পূর্ববর্তী মেমরি ব্লকটি পরীক্ষা করা। যখন আমি একটি অ-উদ্বায়ী মেমরি পরিচালককে বিকাশ করি তখন আমি এই বৈশিষ্ট্যটি ব্যবহার করেছি।


2

সি দৃ strongly়ভাবে টাইপ করা হয় না। একটি স্ট্যান্ডার্ড সি সংকলক অ্যারের সীমা পরীক্ষা করবে না। অন্য জিনিসটি হ'ল সিতে একটি অ্যারে কিছুই নয় যা মেমরির একটি সংক্ষিপ্ত ব্লক এবং সূচি 0 থেকে শুরু হয় তাই -1 এর সূচকটি যা কিছু আগে বিট-প্যাটার্নের অবস্থান a[0]

অন্যান্য ভাষা নেতিবাচক সূচকগুলি একটি দুর্দান্ত উপায়ে ব্যবহার করে explo পাইথনে, a[-1]শেষ উপাদানটি a[-2]ফিরে আসবে, দ্বিতীয় থেকে শেষ উপাদানটি প্রদান করবে এবং আরও কিছু।


2
শক্তিশালী টাইপিং এবং অ্যারে সূচকগুলি কীভাবে সম্পর্কিত? প্রাকৃতিক ভাষার জন্য এমন কোন ভাষা রয়েছে যেখানে অ্যারে সূচকগুলি প্রাকৃতিক হওয়া উচিত?
রাফেল

@ রাফেল যতদূর আমি জানি, শক্ত টাইপিংয়ের অর্থ এই ধরণের ত্রুটি ধরা পড়ে। একটি অ্যারে হ'ল টাইপ, ইনডেক্সআউটআউটবাউন্ডস একটি ত্রুটি তাই দৃ strongly়ভাবে টাইপ করা ভাষায় এটি জানানো হবে, সি-তে এটি করা হবে না। যে আমি বোঝানো কি.
সাদাতাম

আমি যে ভাষাগুলি জানি সেগুলিতে অ্যারে সূচকগুলি টাইপ হয় int, তাই a[-5]এবং আরও সাধারণভাবে int i; ... a[i] = ...;সঠিকভাবে টাইপ করা হয়। সূচী ত্রুটিগুলি কেবল রানটাইমের সময় সনাক্ত করা হয়। অবশ্যই, একটি চালাক সংকলক কিছু লঙ্ঘন সনাক্ত করতে পারে ।
রাফেল

@ রাফেল আমি সামগ্রিকভাবে অ্যারের ডেটা টাইপের কথা বলছি, ইনডেক্সের ধরণের নয়। এটি ব্যাখ্যা করে যে সি কেন ব্যবহারকারীদের একটি [-5] লেখার অনুমতি দেয়। হ্যাঁ, -5 হ'ল সঠিক সূচক প্রকার তবে এটি সীমা ছাড়িয়ে গেছে এবং এটি একটি ত্রুটি। আমার উত্তরে সংকলন বা রানটাইম টাইপ চেকিংয়ের কোনও উল্লেখ নেই।
সাদাতাম

1

সহজ কথায়:

সিতে থাকা সমস্ত ভেরিয়েবল (অ্যারে সহ) মেমরিতে সঞ্চয় করা হয়। ধরা যাক আপনার কাছে "মেমরি" এর 14 বাইট রয়েছে এবং আপনি নিম্নলিখিতটি আরম্ভ করেন:

int a=0;
int array1[6] = {0, 1, 2, 3, 4, 5};

এছাড়াও, একটি বদ্ধমূল্যের আকার 2 বাইট হিসাবে বিবেচনা করুন তারপরে, অনুমানের সাথে মেমরির প্রথম 2 বাইটে পূর্ণসংখ্যা a সংরক্ষণ করা হবে। পরবর্তী 2 বাইটে অ্যারের প্রথম অবস্থানের পূর্ণসংখ্যাটি সংরক্ষণ করা হবে (এর অর্থ অ্যারে [0])।

তারপরে, আপনি যখন অ্যারে বলবেন [-1] হ'ল অ্যারে [0] এর ঠিক আগের মেমরির মধ্যে সংরক্ষিত পূর্ণসংখ্যার কথা উল্লেখ করার মতো, যা আমাদের অনুমাননির্ভর, পূর্ণসংখ্যা ক। বাস্তবে, ভেরিয়েবলগুলি মেমরিতে সংরক্ষণ করা ঠিক এটি নয়।


0
//:Example of negative index:
//:A memory pool with a heap and a stack:

unsigned char memory_pool[64] = {0};

unsigned char* stack = &( memory_pool[ 64 - 1] );
unsigned char* heap  = &( memory_pool[ 0     ] );

int stack_index =    0;
int  heap_index =    0;

//:reserve 4 bytes on stack:
stack_index += 4;

//:reserve 8 bytes on heap:
heap_index  += 8;

//:Read back all reserved memory from stack:
for( int i = 0; i < stack_index; i++ ){
    unsigned char c = stack[ 0 - i ];
    //:do something with c
};;
//:Read back all reserved memory from heap:
for( int i = 0; i < heap_index; i++ ){
    unsigned char c = heap[ 0 + i ];
    //:do something with c
};;

CS.SE এ আপনাকে স্বাগতম! আমরা এমন উত্তরগুলির সন্ধান করছি যা ব্যাখ্যা বা পড়ার বিবরণ সহ আসে। আমরা কোনও কোডিং সাইট নই, এবং আমরা এমন উত্তর চাই না যেগুলি কেবল কোডের একটি ব্লক। আপনি সেই ধরণের তথ্য সরবরাহ করতে নিজের উত্তরটি সম্পাদনা করতে পারবেন কিনা তা বিবেচনা করতে পারেন । ধন্যবাদ!
ডিডাব্লু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.