c - tamim - সি প্রোগ্রামিং ফাংশন




অ্যারে দিয়ে, কেন এটি একটি[5]== 5[একটি]? (12)

জোয়েল স্ট্যাক ওভারফ্লো পডকাস্ট # 34 এ উল্লেখ করেছেন , সি প্রোগ্রামিং ভাষা (উর: কে আর আর) তে, সিটিতে এই অ্যারের এই সম্পত্তিটির উল্লেখ রয়েছে: a[5] == 5[a]

জোয়েল বলছেন যে এটি পয়েন্টার গাণিতিক কারণে কিন্তু আমি এখনও বুঝতে পারছি না। কেন a[5] == 5[a] ?


আক্ষরিক প্রশ্নের উত্তর দিতে। এটা সবসময় সত্য নয় যে x == x

double zero = 0.0;
double a[] = { 0,0,0,0,0, zero/zero}; // NaN
cout << (a[5] == 5[a] ? "true" : "false") << endl;

কপি করে প্রিন্ট

false

আচ্ছা, এটি একটি বৈশিষ্ট্য যা ভাষা সমর্থনের কারণে সম্ভব।

কম্পাইলারটি a[i] হিসাবে *(a+i) এবং এক্সপ্রেশন 5[a] *(5+a) মূল্যায়ন করে। যেহেতু সংযোজনমূলক হয় এটা উভয় সমান যে সক্রিয় আউট। তাই অভিব্যক্তি true মূল্যায়ন।


আমি এই কুৎসিত সিনট্যাক্সটি "দরকারী" হতে পারে, অথবা কমপক্ষে খুব মজাদার যখন আপনি সূচীর অ্যারের সাথে মোকাবিলা করতে চান যা একই অ্যারের মধ্যে অবস্থানগুলি উল্লেখ করে। এটি নেস্টেড বর্গাকার বন্ধনীগুলি প্রতিস্থাপন করতে এবং কোডটিকে আরও পাঠযোগ্য করে তুলতে পারে!

int a[] = { 2 , 3 , 3 , 2 , 4 };
int s = sizeof a / sizeof *a;  //  s == 5

for(int i = 0 ; i < s ; ++i) {  

           cout << a[a[a[i]]] << endl;
           // ... is equivalent to ... 
           cout << i[a][a][a] << endl;  // but I prefer this one, it's easier to increase the level of indirection (without loop)

}

অবশ্যই, আমি নিশ্চিত যে আসল কোডটিতে এর জন্য কোনও ব্যবহারযোগ্য কেস নেই, তবে আমি যেহেতু এটি আকর্ষণীয় মনে করি :)


আমি জানি প্রশ্নের উত্তর দেওয়া হয়েছে, কিন্তু আমি এই ব্যাখ্যাটি ভাগ করতে প্রতিরোধ করতে পারিনি।

আমি কম্পাইলার ডিজাইনের মূলনীতি মনে করি, আসুন একটি অনুমান করা যাক একটি int অ্যারে এবং int আকার 2 বাইট, এবং বেসের ঠিকানা 1000 এর জন্য।

কিভাবে a[5] কাজ করবে ->

Base Address of your Array a + (5*size of(data type for array a))
i.e. 1000 + (5*2) = 1010

সুতরাং,

একইভাবে যখন সি কোডটি 3-ঠিকানা কোডে বিভক্ত হয়, 5[a] হয়ে যাবে ->

Base Address of your Array a + (size of(data type for array a)*5)
i.e. 1000 + (2*5) = 1010 

সুতরাং মূলত উভয় বিবৃতি মেমরির একই অবস্থানের দিকে নির্দেশ করে এবং তাই, a[5] = 5[a]

এই ব্যাখ্যা এছাড়াও কারণ অ্যারে মধ্যে নেতিবাচক সূচী সি মধ্যে কাজ করে।

অর্থাৎ যদি আমি a[-5] অ্যাক্সেস করি তবে এটি আমাকে দেবে

Base Address of your Array a + (-5 * size of(data type for array a))
i.e. 1000 + (-5*2) = 990

এটা 9 0 নম্বর স্থানে আমার বস্তু ফিরে আসবে।


এটি Ted জেনসেন দ্বারা একটি টিউটোরিয়াল উপর পয়েন্টার এবং সি এ AR তে খুব ভাল ব্যাখ্যা আছে।

টেড জেনসেন এটিকে ব্যাখ্যা করেছেন:

প্রকৃতপক্ষে, এটি সত্য, অর্থাৎ যেখানেই কেউ লিখবে a[i] এটি কোন সমস্যা ছাড়াই *(a + i) দিয়ে প্রতিস্থাপিত করা যেতে পারে। আসলে, কম্পাইলার একই ক্ষেত্রে একই কোড তৈরি করবে। সুতরাং আমরা দেখি যে পয়েন্টার গাণিতিকটি অ্যারে সূচী হিসাবে একই জিনিস। হয় সিনট্যাক্স একই ফলাফল উত্পাদন করে।

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

এখন, এই শেষ অভিব্যক্তিটির দিকে তাকিয়ে দেখুন, এটির অংশ .. (a + i) , + অপারেটর এবং সি রাষ্ট্রের নিয়মগুলি ব্যবহার করে একটি সহজ সংযোজন যা এইরকম অভিব্যক্তিটি ক্রমাগত। যে (একটি + আমি) অনুরূপ (i + a) । সুতরাং আমরা *(i + a) সহজেই *(a + i) লিখতে পারি। কিন্তু *(i + a) i[a] আসতে পারে i[a] ! এই সব থেকে অদ্ভুত সত্য আসে যে যদি:

char a[20];

লেখা

a[3] = 'x';

লেখা হিসাবে একই

3[a] = 'x';

এবং অবশ্যই

 ("ABCD"[2] == 2["ABCD"]) && (2["ABCD"] == 'C') && ("ABCD"[2] == 'C')

এর মূল কারণ হল 70 এর দশকে যখন সি ডিজাইন করা হয়েছিল, তখন কম্পিউটারগুলিতে অনেক মেমরি ছিল না (64KB অনেক ছিল), তাই সি কম্পাইলারটি অনেক সিনট্যাক্স চেকিং করেনি। অতএব " X[Y] " বরং অন্ধভাবে " *(X+Y) " তে অনুবাদ করা হয়েছিল "

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


চমৎকার প্রশ্ন / উত্তর।

শুধু নির্দেশ করতে চান যে সি পয়েন্টার এবং অ্যারে একই নয় , যদিও এই ক্ষেত্রে পার্থক্য অপরিহার্য নয়।

নিম্নলিখিত ঘোষণা বিবেচনা করুন:

int a[10];
int* p = a;

A.out এ , প্রতীকটি এমন একটি ঠিকানায় থাকে যা অ্যারেটির শুরুতে এবং প্রতীকটি এমন একটি ঠিকানায় যেখানে একটি পয়েন্টার সংরক্ষণ করা হয় এবং মেমরির অবস্থানের পয়েন্টারের মান অ্যারেটির শুরু।


পয়েন্টার ধরনের

1) তথ্য পয়েন্টার

int *ptr;

2) তথ্য কোস্ট পয়েন্টার

int const *ptr;

3) কনস্টেবল তথ্য কনস্টেবল পয়েন্টার

int const *const ptr;

এবং অ্যারে আমাদের তালিকা থেকে (2) টাইপ
যখন আপনি একটি সময়ে একটি অ্যারে সংজ্ঞায়িত করেন তখন একটি পয়েন্টারটি সেই পয়েন্টারে প্রারম্ভিক হয়
আমরা জানি যে আমরা আমাদের প্রোগ্রামে কনস্ট্যান্ট পরিবর্তন বা পরিবর্তন করতে পারছি না কারণ এটি কম্পাইল সময়টিতে ERROR ছুড়ে ফেলে

আমি পাওয়া প্রধান পার্থক্য হয় ...

আমরা একটি ঠিকানা দ্বারা পয়েন্টার পুনরায় আরম্ভ করতে পারেন কিন্তু একটি অ্যারে সঙ্গে একই ক্ষেত্রে না।

======
এবং আপনার প্রশ্ন ফিরে ...
একটি [5] কিছুই কিন্তু * (একটি + 5)
আপনি সহজে বুঝতে পারেন
আমাদের তালিকাতে একটি (2) পয়েন্টারের মতো একটি ঠিকানা সম্বলিত ঠিকানা (লোকেরা এটি বেস ঠিকানা হিসাবে কল করে)
[] - অপারেটর পয়েন্টার * সঙ্গে প্রতিস্থাপনযোগ্য হতে পারে।

তাই অবশেষে ...

a[5] == *(a +5) == *(5 + a) == 5[a] 

সি

 int a[]={10,20,30,40,50};
 int *p=a;
 printf("%d\n",*p++);//output will be 10
 printf("%d\n",*a++);//will give an error

পয়েন্টার একটি "পরিবর্তনশীল"

অ্যারের নাম একটি "স্মারক" বা "synonym"

p++; বৈধ কিন্তু a++ অবৈধ

a[2] সমান 2 [একটি] কারণ এই উভয় অভ্যন্তরীণ অপারেশন হয়

"পয়েন্টার গাণিতিক" অভ্যন্তরীণভাবে গণনা করা হয়

*(a+3) সমান *(3+a)


সি কম্পাইলার মধ্যে

a[i]
i[a]
*(a+i)

একটি অ্যারে একটি উপাদান উল্লেখ করার বিভিন্ন উপায়! (সমস্ত পোশাক নেই)


সি মান নিম্নরূপ [] অপারেটর সংজ্ঞায়িত করে:

a[b] == *(a + b)

অতএব a[5] মূল্যায়ন করবে:

*(a + 5)

এবং 5[a] মূল্যায়ন করা হবে:

*(5 + a)

a অ্যারের প্রথম উপাদান একটি পয়েন্টার। a[5] হল 5 টি উপাদান যা a থেকে 5 টি উপাদান , যা *(a + 5) , এবং প্রাথমিক স্কুল গণিতের থেকে আমরা যা জানি তা সমান (অতিরিক্ত commutative )।


সি অ্যারের মধ্যে , arr[3] এবং 3[arr] একই, এবং তাদের সমান পয়েন্টার নোটেশনগুলি *(arr + 3) থেকে *(3 + arr) । কিন্তু বিপরীতভাবে [arr]3 বা [3]arr সঠিক নয় এবং সিনট্যাক্স ত্রুটির ফলে হবে, যেমন (arr + 3)* এবং (3 + arr)* বৈধ এক্সপ্রেশন নয়। কারণটি হ'ল ডেরিফেন্স অপারেটরটি ঠিকানার পরে নয়, এক্সপ্রেশন দ্বারা প্রদত্ত ঠিকানাটির আগে স্থাপন করা উচিত।





pointer-arithmetic