কেন একটি অ্যারেতে সূচকটি সি দিয়ে শূন্য দিয়ে শুরু হয় এবং 1 দিয়ে নয়?
কেন একটি অ্যারেতে সূচকটি সি দিয়ে শূন্য দিয়ে শুরু হয় এবং 1 দিয়ে নয়?
উত্তর:
সি-তে, একটি অ্যারের নামটি মূলত একটি পয়েন্টার [তবে মন্তব্যগুলি দেখুন] , একটি মেমরি অবস্থানের একটি উল্লেখ এবং তাই অভিব্যক্তিটি সূচনা উপাদান থেকে দূরে array[n]
কোনও মেমরি অবস্থানের n
উপাদানগুলিকে বোঝায় । এর অর্থ সূচকটি অফসেট হিসাবে ব্যবহৃত হয়। অ্যারের প্রথম উপাদানটি ঠিক মেমরি অবস্থানের মধ্যে থাকে যা অ্যারে উল্লেখ করে (0 উপাদান দূরে), তাই এটি হিসাবে চিহ্নিত করা উচিত array[0]
।
আরও তথ্যের জন্য:
http://developeronline.blogspot.com/2008/04/why-array-index-should-start-from-0.html
sizeof arr
অ্যারে অবজেক্টের আকার দেয়, পয়েন্টারের আকার নয়।
sizeof
অপারেটরের অপারেন্ড বা অ্যানারি &
অপারেটর ব্যতীত বা কোনও অ্যারে আরম্ভ করার জন্য স্ট্রিং আক্ষরিক ব্যবহৃত হয়, " এক্সার "টাইপযুক্ত একটি এক্সপ্রেশন টাইপ "টাইপ করে" টাইপ করে "পয়েন্টার টু টাইপ" দিয়ে অভিব্যক্তিতে রূপান্তরিত হয় যা অ্যারে অবজেক্টের প্রাথমিক উপাদানটিকে নির্দেশ করে এবং লভাল্যু হয় না। অ্যারে অবজেক্টটি যদি স্টোরেজ ক্লাসে নিবন্ধ করে থাকে তবে আচরণটি অপরিবর্তিত থাকে। "
এই প্রশ্নটি এক বছর আগে পোস্ট করা হয়েছিল, তবে এখানে ...
যদিও ডিজকাস্ত্রের নিবন্ধ (বর্তমানে মুছে দেওয়া উত্তরে আগে উল্লেখ করা হয়েছে ) গাণিতিক দৃষ্টিকোণ থেকে বোঝা যায়, প্রোগ্রামিংয়ের ক্ষেত্রে এটি তেমন প্রাসঙ্গিক নয় ।
ভাষা স্পেসিফিকেশন এবং সংকলক-ডিজাইনারগণের দ্বারা নেওয়া সিদ্ধান্ত কম্পিউটার সিস্টেম-ডিজাইনারগণের গণনা 0-তে শুরু করার সিদ্ধান্তের ভিত্তিতে হয়।
ড্যানি কোহেনের একটি প্লাই ফর পিস থেকে উদ্ধৃতি দেওয়া ।
যে কোনও বেস খের জন্য, প্রথম বি ^ এন অ-নেতিবাচক পূর্ণসংখ্যাগুলি ঠিক এন ডিজিট দ্বারা প্রতিনিধিত্ব করা হয় (শীর্ষস্থানীয় শূন্যগুলি সহ) কেবল যদি নম্বরটি 0 থেকে শুরু হয়।
এটি বেশ সহজে পরীক্ষা করা যায়। বেস -২ এ, 2^3 = 8
অষ্টম নম্বরটি নিন:
111
3
বিট ব্যবহার করে উপস্থাপন করা যেতে পারে , যখন 1000
অতিরিক্ত বিট (4 বিট) লাগবে।
কম্পিউটারের মেমোরি অ্যাড্রেসে 2^N
কোষগুলি N
বিট দ্বারা সম্বোধন করা থাকে । এখন যদি আমরা 1 এ গণনা শুরু করি, 2^N
কক্ষগুলির N+1
ঠিকানা লাইনগুলির প্রয়োজন হবে । ঠিক 1 ঠিকানা অ্যাক্সেস করতে অতিরিক্ত বিটের প্রয়োজন। ( 1000
উপরের ক্ষেত্রে।) এটির সমাধানের আরেকটি উপায় হ'ল শেষ ঠিকানাটি অ্যাক্সেসযোগ্য ছেড়ে দেওয়া, এবং N
ঠিকানা লাইনগুলি ব্যবহার করা ।
উভয়ই উপ-অনুকূল সমাধান , 0 এ গণনা শুরু করার সাথে তুলনা করে, যা ঠিকানার ঠিকানাগুলি ব্যবহার করে সমস্ত ঠিকানাকে অ্যাক্সেসযোগ্য রাখে N
!
গণনা শুরু করার সিদ্ধান্ত 0
, তারপরে তাদের উপর চলমান সফ্টওয়্যার সহ সমস্ত ডিজিটাল সিস্টেমকে ঘিরে রেখেছে , কারণ কোডটি অন্তর্নিহিত সিস্টেমটি কী ব্যাখ্যা করতে পারে তা অনুবাদ করা সহজ করে তোলে। যদি এটি না হয়, তবে প্রতিটি অ্যারের অ্যাক্সেসের জন্য মেশিন এবং প্রোগ্রামার মধ্যে একটি অপ্রয়োজনীয় অনুবাদ অপারেশন থাকত। এটি সংকলন সহজ করে তোলে।
কাগজ থেকে উদ্ধৃতি:
a[b]
মতো কার্যকর হয়েছিল *(a+b)
। আজও আপনি এখনও 2[a]
পরিবর্তে লিখতে পারেন a[2]
। এখন যদি সূচকগুলি 0 থেকে শুরু না হয় তবে a[b]
তা পরিবর্তিত হবে *(a+b-1)
। এর জন্য 0 এর পরিবর্তে সময়ের সিপিইউগুলিতে 2 টি সংযোজন প্রয়োজন হবে, যার অর্থ অর্ধেক গতি। স্পষ্টতই কাম্য নয়।
কারণ 0 অ্যারের মাথা থেকে পয়েন্টার থেকে অ্যারের প্রথম উপাদানটির কত দূরে।
বিবেচনা:
int foo[5] = {1,2,3,4,5};
0 টি অ্যাক্সেস করতে আমরা করি:
foo[0]
তবে foo একটি পয়েন্টারের কাছে পচে যায় এবং উপরের অ্যাক্সেসটিতে অ্যাক্সেসের আনুষাঙ্গিক গাণিতিক পদ্ধতি রয়েছে
*(foo + 0)
আজকাল পয়েন্টার গাণিতিক হিসাবে ঘন ঘন ব্যবহৃত হয় না। যদিও ফিরে, এটি কোনও ঠিকানা নেওয়া এবং X "ইনট" সরানোর দিক থেকে দূরে সরিয়ে নেওয়া সুবিধাজনক উপায়। অবশ্যই আপনি যেখানে থাকতে চান সেখানে থাকতে চাইলে আপনি কেবল 0 যুক্ত করুন!
কারণ 0-ভিত্তিক সূচক ...
array[index]
... হিসাবে প্রয়োগ করা হবে ...
*(array + index)
যদি সূচকটি 1-ভিত্তিক হয় তবে সংকলকটি তৈরি করতে হবে: *(array + index - 1)
এবং এটি "-1" পারফরম্যান্সকে ক্ষতিগ্রস্থ করবে।
কারণ এটি সংকলক এবং লিঙ্কারটিকে সহজতর (লিখতে সহজ) করেছে।
"... একটি ঠিকানা এবং একটি অফসেট দ্বারা মেমরির উল্লেখ করা কার্যত সমস্ত কম্পিউটার আর্কিটেকচারে হার্ডওয়্যারে সরাসরি উপস্থাপন করা হয়, সুতরাং সিতে এই নকশার বিবরণ সংকলন সহজ করে তোলে"
এবং
"... এটি একটি সহজ বাস্তবায়ন করে তোলে ..."
অ্যারে সূচক সর্বদা শূন্য দিয়ে শুরু হয় L অনুমান করি বেস ঠিকানাটি 2000. এখন arr[i] = *(arr+i)
। এখন if i= 0
, এর অর্থ *(2000+0
) অ্যারেতে প্রথম ঠিকানাটির ভিত্তি ঠিকানা বা ঠিকানার সমান। এই সূচকটিকে অফসেট হিসাবে বিবেচনা করা হয়, তাই বাইফায়াল্ট সূচকটি শূন্য থেকে শুরু হয়।
একই কারণে, যখন এটি বুধবার এবং কেউ আপনাকে বুধবার পর্যন্ত কত দিন জিজ্ঞাসা করে, আপনি 1 এর পরিবর্তে 0 বলুন, এবং এটি যখন বুধবার এবং কেউ আপনাকে বৃহস্পতিবার পর্যন্ত কত দিন জিজ্ঞাসা করবে, আপনি 2 না বলে 1 বলবেন।
শূন্য-ভিত্তিক সংখ্যার জন্য আমি যে সবচেয়ে মার্জিত ব্যাখ্যাটি পড়েছি তা হ'ল একটি পর্যবেক্ষণ যা মান রেখার চিহ্নিত স্থানগুলিতে সংরক্ষণ করা হয় না, বরং তাদের মধ্যে ফাঁকা স্থানগুলিতে থাকে। প্রথম আইটেমটি শূন্য এবং একের মধ্যে, পরেরটি এক এবং দু'একটির মধ্যে সংরক্ষণ করা হয়। এনথ আইটেমটি এন -1 এবং এন এর মধ্যে সংরক্ষণ করা হয়। উভয় পক্ষের সংখ্যা ব্যবহার করে আইটেমের একটি পরিসর বর্ণিত হতে পারে। স্বতন্ত্র আইটেমগুলি নীচের সংখ্যাগুলি ব্যবহার করে বর্ণিত কনভেনশন দ্বারা হয়। যদি কাউকে একটি ব্যাপ্তি দেওয়া হয় (এক্স, ওয়াই), নীচের সংখ্যাটি ব্যবহার করে স্বতন্ত্র সংখ্যা সনাক্তকরণের অর্থ হ'ল যে কোনও পাটিগণিত (এটি আইটেম এক্স) ব্যবহার না করেই প্রথম আইটেমটি সনাক্ত করতে পারে তবে শেষ আইটেমটি সনাক্ত করার জন্য একটিকে অবশ্যই Y থেকে বিয়োগ করতে হবে (Y) -1)। উপরের নম্বরটি ব্যবহার করে আইটেমগুলি সনাক্ত করা কোনও পরিসরে শেষ আইটেমটি সনাক্ত করা সহজ করবে (এটি আইটেম হবে Y),
যদিও উপরের সংখ্যার উপর ভিত্তি করে আইটেমগুলি সনাক্ত করা ভয়াবহ হবে না, তবে রেঞ্জের প্রথম আইটেমটি (এক্স, ওয়াই) হিসাবে নির্ধারণ করা X এর উপরের একটি হিসাবে সাধারণত এটি নীচের অংশ হিসাবে সংজ্ঞায়িত করার চেয়ে আরও সুন্দরভাবে কাজ করে (এক্স + 1)।
প্রযুক্তিগত কারণটি এই সত্য থেকে উদ্ভূত হতে পারে যে অ্যারের মেমরির অবস্থানের দিকে নির্দেশকটি অ্যারের প্রথম উপাদানটির বিষয়বস্তু। আপনি যদি কোনওটির সূচক দিয়ে পয়েন্টারটি ঘোষণা করেন, প্রোগ্রামগুলি অবশ্যই আপনার সামগ্রীতে যা চান তা নয় যা অ্যাক্সেস করতে পয়েন্টারে অবশ্যই একটির মান যোগ করে।
এক্স ব্যবহার করে একটি পিক্সেল স্ক্রিন অ্যাক্সেস করার চেষ্টা করুন, ওয়াই 1-ভিত্তিক ম্যাট্রিক্সে স্থানাঙ্ক করে। সূত্রটি সম্পূর্ণ জটিল। জটিল কেন? কারণ আপনি এক্স, ওয়াই কর্ডটিকে একটি সংখ্যায়, অফসেটে রূপান্তর করেন। আপনাকে কেন অফসেটে এক্স, ওয়াই রূপান্তর করতে হবে? কারণ মেমরি কোষের একটি অবিচ্ছিন্ন ধারা (অ্যারে) হিসাবে কম্পিউটারের অভ্যন্তরে মেমরিটি এভাবেই সংগঠিত হয়। কীভাবে কম্পিউটার অ্যারে সেলগুলি ব্যবহার করে? অফসেট ব্যবহার করে (প্রথম ঘর থেকে স্থানচ্যুতি, শূন্য-ভিত্তিক সূচক মডেল)।
সুতরাং কোডের এক পর্যায়ে আপনার প্রয়োজনীয় (বা সংকলকটির প্রয়োজন) 1-বেস সূত্রকে 0-ভিত্তিক সূত্রে রূপান্তর করতে হবে কারণ কম্পিউটারগুলি মেমরির সাথে এইভাবে ডিল করে।
ধরুন আমরা আকারের একটি অ্যারে 5
ইন্টি অ্যারে তৈরি করতে চাই [5] = [2,3,5,9,8]
অ্যারের প্রথম উপাদানটি 100 এর দিকে চিহ্নিত করা
যাক এবং আমরা সূচীকরণটি 1 থেকে নয় 1 থেকে শুরু করে বিবেচনা করি 0.
এখন সূচকের সাহায্যে আমাদের 1 ম উপাদানটির অবস্থানটি খুঁজে পেতে হবে
(মনে রাখবেন 1 ম উপাদানটির অবস্থান 100 হয়)
যেহেতু একটি পূর্ণসংখ্যার আকার 4-বিট
হয় -> সূচক 1 বিবেচনা করে অবস্থানের
আকার হবে সূচকের (1) * পূর্ণসংখ্যার আকার (4) = 4
সুতরাং এটি আমাদের প্রদর্শিত আসল অবস্থানটি
100 + 4 = 104
যা সত্য নয় কারণ প্রাথমিক অবস্থানটি 100 এ ছিল 100
এটি 1004 এ নির্দেশ করা উচিত 104 নয়
এটি
এখন ভুল is ধরুন আমরা 0 থেকে সূচীটি গ্রহণ করেছি
তবে
1 ম উপাদানটির অবস্থান
সূচক (0) * আকারের আকার হতে হবে (4) = 0
অতএব ->
1 ম উপাদানটির অবস্থান 100 + 0 = 100
এবং এটি উপাদানটির আসল অবস্থান ছিল এ
কারণেই সূচী 0 থেকে শুরু হয়;
আমি আশা করি এটি আপনার বক্তব্য পরিষ্কার করবে।
আমি জাভা ব্যাকগ্রাউন্ড থেকে এসেছি। আমি নীচের চিত্রটিতে এই প্রশ্নের উত্তর উপস্থাপন করেছি যার নীচে আমি একটি কাগজের টুকরোতে লিখেছি যা স্ব-বর্ণনামূলক
প্রধান পদক্ষেপ:
দ্রষ্টব্য : ছবিতে প্রদর্শিত ব্লকগুলি মেমরির উপস্থাপনা
প্রথমে আপনার জানা দরকার যে অ্যারেগুলি অভ্যন্তরীণভাবে পয়েন্টার হিসাবে বিবেচিত হয় কারণ "অ্যারের নামটিতে নিজেই অ্যারের প্রথম উপাদানটির ঠিকানা থাকে"
ex. int arr[2] = {5,4};
অ্যারে ঠিকানা 100 এ শুরু হয় তা বিবেচনা করুন তাই উপাদানটির প্রথম উপাদানটি 100 নম্বরের ঠিকানায় হবে এবং দ্বিতীয়টি এখন 104-এ থাকবে, বিবেচনা করুন যে অ্যারে সূচক 1 থেকে শুরু হয়, তাই
arr[1]:-
এটি পয়েন্টার এক্সপ্রেশনতে এভাবে লেখা যেতে পারে-
arr[1] = *(arr + 1 * (size of single element of array));
ইন্টের আকার 4 বাইটস এখন বিবেচনা করুন,
arr[1] = *(arr + 1 * (4) );
arr[1] = *(arr + 4);
যেহেতু আমরা জানি অ্যারে নামটিতে তার প্রথম উপাদানটির ঠিকানা রয়েছে তাই এখন arr = 100,
arr[1] = *(100 + 4);
arr[1] = *(104);
যা দেয়,
arr[1] = 4;
এই অভিব্যক্তিটির কারণে আমরা 100 ঠিকানায় উপাদানটি অ্যাক্সেস করতে পারিনি যা অফিশিয়াল প্রথম উপাদান,
এখন বিবেচনা করুন অ্যারে সূচক 0 থেকে শুরু হয়, তাই
arr[0]:-
এটি হিসাবে সমাধান করা হবে
arr[0] = *(arr + 0 + (size of type of array));
arr[0] = *(arr + 0 * 4);
arr[0] = *(arr + 0);
arr[0] = *(arr);
এখন, আমরা জানি যে অ্যারের নামটিতে এর প্রথম উপাদানটির ঠিকানা রয়েছে তাই,
arr[0] = *(100);
যা সঠিক ফলাফল দেয়
arr[0] = 5;
সুতরাং অ্যারে সূচক সর্বদা 0 থেকে শুরু হয় সি।
তথ্যসূত্র: সমস্ত বিবরণ বইতে লিখেছেন "ব্রায়ান কার্নিংহান এবং ডেনিস রিচি র সি প্রোগ্রামিং ল্যাঙ্গুয়েজ"
অ্যারেতে, সূচকটি প্রাথমিক উপাদান থেকে দূরত্বটি জানায়। সুতরাং, প্রথম উপাদানটি প্রাথমিক উপাদান থেকে 0 দূরত্বে রয়েছে। সুতরাং, তাই 0 থেকে অ্যারে শুরু।
এটা কারণ address
element
অ্যারে ডানদিকে নির্দেশ করতে । আসুন নীচের অ্যারে ধরে নিই:
let arr = [10, 20, 40, 60];
আসুন আমরা এখন ঠিকানাটির শুরুটি বিবেচনা করি 12
এবং মাপ element
হতে 4 bytes
।
address of arr[0] = 12 + (0 * 4) => 12
address of arr[1] = 12 + (1 * 4) => 16
address of arr[2] = 12 + (2 * 4) => 20
address of arr[3] = 12 + (3 * 4) => 24
যদি এটি ছিল না zero-based
, টেকনিক্যালি আমাদের প্রথম উপাদান ঠিকানা array
হবে 16
যা ভুল এটা এর অবস্থান হিসাবে 12
।
অ্যারের নামটি একটি স্থির পয়েন্টার যা বেস ঠিকানায় নির্দেশ করে W আপনি যখন আরার ব্যবহার করেন [i] সংকলক এটি * (আরআর + আই) হিসাবে ম্যানিপুলেট করে int negativeণাত্মক সংখ্যা এবং 0 থেকে 128 ধনাত্মক সংখ্যা o সুতরাং অ্যারে সূচক সর্বদা শূন্য দিয়ে শুরু হয়।
int
কমপক্ষে একটি 16-বিট পরিসীমা সমর্থন করার জন্য একটি প্রকারের প্রয়োজন, এবং বেশিরভাগ সিস্টেমে আজকাল 32-বিট সমর্থন করে। আমি মনে করি আপনার যুক্তি ত্রুটিযুক্ত এবং আপনার উত্তর ইতিমধ্যে অন্যান্য লোকদের সরবরাহ করা অন্যান্য উত্তরগুলির উন্নতি করতে পারে না। আমি এটি মুছে ফেলার পরামর্শ দিচ্ছি।