পয়েন্টার ক্ষয় থেকে অ্যারে কি?


384

পয়েন্টার ক্ষয় থেকে অ্যারে কি? অ্যারে পয়েন্টারগুলির সাথে কি কোনও সম্পর্ক আছে?


73
অল্প পরিচিত: অ্যানারি প্লাস অপারেটরটি "ক্ষয় অপারেটর" হিসাবে ব্যবহার করা যেতে পারে: প্রদত্ত int a[10]; int b(void);, তারপরে +aএকটি ইনট পয়েন্টার এবং +bএটি একটি ফাংশন পয়েন্টার। আপনি যদি কোনও রেফারেন্স গ্রহণ করে কোনও টেম্পলেটটিতে এটি পাস করতে চান তবে দরকারী।
জোহানেস স্কাউব -

3
@ লিটব - প্যারেনগুলি একই কাজ করবে (যেমন, (ক) একটি অভিব্যক্তি হওয়া উচিত যা কোনও পয়েন্টারের কাছে মূল্যায়ন করে), ঠিক ?.
মাইকেল বুড়

21
std::decayসি ++ থেকে অ্যানারি + এর উপরে অ্যারে ক্ষয় করার একটি কম অস্পষ্ট উপায় way
কিংবদন্তি 2 কে

21
@ JohannesSchaub-litb এই প্রশ্নের উভয় C ও C ছাগু ট্যাগ করা হয় যেহেতু ++ আমি নির্মল যদিও চাই যে +aএবং +bসি আইনি হয় ++ এটা সি (অবৈধ C11 6.5.3.3/1 "ইউনারী এর প্রতীক +বা -অপারেটর থাকিবে পাটিগণিতের ধরণ ")
এমএম

5
@ প্রত্যাখ্যান তবে আমি অনুমান করি যে এটি আনরিয়া + এর সাথে কৌশল হিসাবে খুব কম পরিচিত নয়। আমি যে কারণে এটি উল্লেখ করেছি তা কেবল এটি ক্ষয় হওয়ার কারণে নয়, কারণ এটি খেলতে মজাদার কিছু জিনিস;)
জোহানেস স্কাউব - লিটব

উত্তর:


283

এটি অ্যারে পয়েন্টারগুলিতে "ক্ষয়" হয় বলেছে। হিসাবে ঘোষিত একটি সি ++ অ্যারে int numbers [5]পুনরায় নির্দেশিত হতে পারে না, অর্থাত্ আপনি বলতে পারবেন না numbers = 0x5a5aff23। আরও গুরুত্বপূর্ণভাবে ক্ষয় শব্দটি ধরণ এবং মাত্রা হ্রাস নির্দেশ করে; মাত্রা তথ্য (গণনা 5) হারাতে গিয়ে numbersক্ষয় int*হ'ল এবং প্রকারটি আর হয় না int [5]। এখানে দেখুন ক্ষেত্রে যেখানে ক্ষয় ঘটে না

যদি আপনি মান অনুসারে একটি অ্যারে পাস করেন তবে আপনি যা করছেন তা একটি পয়েন্টারটি অনুলিপি করছেন - অ্যারের প্রথম উপাদানটির একটি পয়েন্টার প্যারামিটারে অনুলিপি করা হয়েছে (যার ধরণের বিন্যাসে অ্যারের উপাদানটির ধরণও হওয়া উচিত)। এটি অ্যারের ক্ষয় প্রকৃতির কারণে কাজ করে; একবার ক্ষয় হয়ে গেলে sizeofআর সম্পূর্ণ অ্যারের আকার দেয় না, কারণ এটি মূলত পয়েন্টার হয়ে যায়। এ কারণেই রেফারেন্স বা পয়েন্টার দিয়ে পাস করা পছন্দ করা (অন্যান্য কারণগুলির মধ্যে)।

অ্যারেতে যাওয়ার তিনটি উপায় 1 :

void by_value(const T* array)   // const T array[] means the same
void by_pointer(const T (*array)[U])
void by_reference(const T (&array)[U])

শেষ দুটি যথাযথ sizeofতথ্য দেবে, যখন অ্যারে আর্গুমেন্টটি প্যারামিটারে বরাদ্দ দেওয়ার ক্ষয় হয় না বলে প্রথমটি তা দেয় না।

1 ধ্রুবক ইউ সংকলন সময়ে জানা উচিত।


8
মান দ্বারা প্রথম পাস কিভাবে?
rlbond

10
বাই_ভ্যালু অ্যারের প্রথম উপাদানটিতে একটি পয়েন্টার দিয়ে যাচ্ছে; ফাংশন পরামিতি প্রসঙ্গে, T a[]অনুরূপ T *a। বাই_পয়েন্টার একই জিনিসটি পার করছে, পয়েন্টারের মানটি এখন যোগ্যতা ছাড়াই const। আপনি যদি অ্যারেতে কোনও পয়েন্টারটি পাস করতে চান ( অ্যারের প্রথম উপাদানটির সাথে একটি পয়েন্টারের বিপরীতে), সিনট্যাক্সটি হয় T (*array)[U]
জন বোড

4
"সেই অ্যারেতে সুস্পষ্ট পয়েন্টার সহ" - এটি ভুল। যদি aএটির অ্যারে হয় charতবে aতা ধরণের char[N], এবং ক্ষয় হবে char*; তবে &aএটি ধরণের char(*)[N]এবং ক্ষয় হবে না
পাভেল মিনায়েভ

5
@ ফ্রেড ওভারফ্লো: সুতরাং যদি Uপরিবর্তনগুলি হয় তবে আপনাকে দুটি জায়গায় এটি পরিবর্তন করতে মনে করতে হবে না, বা নীরব বাগগুলি ঝুঁকিপূর্ণ ... স্বায়ত্তশাসন!
অরবিট

4
"আপনি যদি মান অনুসারে একটি অ্যারে পাস করেন তবে আপনি যা করছেন তা একটি পয়েন্টার অনুলিপি করছে" এটি কোনও অর্থ দেয় না, কারণ অ্যারেগুলি মান, সময়কাল দিয়ে পাস করা যায় না।
juanchopanza

103

অ্যারেগুলি মূলত সি / সি ++ এর পয়েন্টারগুলির সমান, তবে বেশ নয়। একবার আপনি একটি অ্যারে রূপান্তর করুন:

const int a[] = { 2, 3, 5, 7, 11 };

পয়েন্টারে (যা কাস্টিং ব্যতীত কাজ করে এবং তাই কিছু ক্ষেত্রে অপ্রত্যাশিতভাবে ঘটতে পারে):

const int* p = a;

আপনি sizeofঅ্যারেতে উপাদান গণনা করে অপারেটরের ক্ষমতা হারাবেন :

assert( sizeof(p) != sizeof(a) );  // sizes are not equal

এই হারানো ক্ষমতাটিকে "ক্ষয়" হিসাবে উল্লেখ করা হয়।

আরও বিশদের জন্য, অ্যারে ক্ষয় সম্পর্কে এই নিবন্ধটি দেখুন


51
অ্যারেগুলির হয় না মূলত পয়েন্টার হিসাবে একই; তারা সম্পূর্ণ ভিন্ন প্রাণী। বেশিরভাগ প্রসঙ্গে, একটি অ্যারের এমনভাবে আচরণ করা যেতে পারে যেমন এটি পয়েন্টার ছিল, এবং একটি পয়েন্টারটিকে যেমন অ্যারে বলে মনে করা যেতে পারে তবে এটি যতটা কাছে আসে তত কাছাকাছি।
জন বোদে

20
@ জন, দয়া করে আমার ভুল ভাষাকে ক্ষমা করুন। আমি দীর্ঘ ব্যাকস্টোরিতে জড়িয়ে না পড়ে উত্তরটি পাওয়ার চেষ্টা করছিলাম, এবং "মূলত ... তবে বেশ নয়" যেমনটা আমি কলেজে পেয়েছি, ততই ভালো ব্যাখ্যা। আমি নিশ্চিত যে আগ্রহী কেউই আপনার আপত্তিকৃত মন্তব্য থেকে আরও সঠিক ছবি পেতে পারে get
সিস্টেম PAUSE


47

মানক কী বলে তা এখানে (সি 99 6.3.2.1/3 - অন্যান্য অপারেশনস - লভ্যালু, অ্যারে এবং ফাংশন ডিজাইনার):

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

এর অর্থ এই যে অ্যারে নামটি কোনও অভিব্যক্তি হিসাবে ব্যবহৃত হয়, এটি স্বয়ংক্রিয়ভাবে বিন্যাসে অ্যারের 1 ম আইটেমে রূপান্তরিত হয়।

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

সি ++ স্ট্যান্ডার্ড (৪.২ অ্যারে-থেকে-পয়েন্টার রূপান্তর) রূপান্তরকরণের প্রয়োজনীয়তাটি (জোর দিয়ে খনি) আলগা করে:

"NT এর অ্যারে" বা "টি এর অজানা বাউন্ডির অ্যারে" টাইপের একটি মান বা মূল্যকে টাইপ " টি পয়েন্টারে" রূপান্তরিত করা যেতে পারে ”

সুতরাং রূপান্তর না আছে ঘটতে এটা প্রায় কাছাকাছি সবসময় সি মত (এই ফাংশন জমিদার দেয় বা টেমপ্লেট অ্যারের ধরনের উপর মেলে)।

সি এ কারণেই আপনাকে ফাংশন প্রোটোটাইপস / সংজ্ঞাগুলিতে অ্যারে প্যারামিটারগুলি ব্যবহার করা এড়ানো উচিত (আমার মতে - কোনও সাধারণ চুক্তি আছে কিনা তা আমি নিশ্চিত নই)। এগুলি বিভ্রান্তি সৃষ্টি করে এবং যাইহোক একটি কল্পকাহিনী - পয়েন্টার পরামিতি ব্যবহার করুন এবং বিভ্রান্তি পুরোপুরি না চলে যেতে পারে তবে কমপক্ষে প্যারামিটারের ঘোষণাটি মিথ্যা নয়।


2
কোডের একটি উদাহরণ লাইন কী যেখানে "" ধরণের অ্যারে টাইপযুক্ত এক্সপ্রেশন "" একটি অ্যারে শুরু করার জন্য ব্যবহৃত একটি স্ট্রিং আক্ষরিক "?
গ্যারেট

4
@Garrett char x[] = "Hello";। 6 টি উপাদানের অ্যারে "Hello"ক্ষয় হয় না; পরিবর্তে xআকার পায় 6এবং এর উপাদানগুলির উপাদানগুলি থেকে আরম্ভ করা হয় "Hello"
এমএম

30

"ক্ষয়" বলতে কোনও অ্যারে টাইপ থেকে পয়েন্টার টাইপের ক্ষেত্রে কোনও অভিব্যক্তির অন্তর্নিহিত রূপান্তরকে বোঝায়। বেশিরভাগ প্রসঙ্গে, যখন সংকলক একটি অ্যারে এক্সপ্রেশন দেখে এটি "T এর এন-এলিমেন্ট অ্যারে" থেকে "পয়েন্টার টিতে" রূপান্তরিত করে এবং অ্যারের প্রথম উপাদানটির ঠিকানায় অভিব্যক্তির মান সেট করে sets । এই নিয়মের ব্যতিক্রমগুলি হ'ল যখন কোনও অ্যারে sizeofবা &অপারেটরগুলির একটি অপরেন্ড হয় , বা অ্যারে একটি স্ট্রিং আক্ষরিক হয় যা একটি ঘোষণায় প্রারম্ভিক হিসাবে ব্যবহৃত হয়।

নিম্নলিখিত কোডটি ধরুন:

char a[80];
strcpy(a, "This is a test");

এক্সপ্রেশনটি a"চর-এর 80-অ্যারের অ্যারে" প্রকারের এবং "এটি একটি পরীক্ষা" এক্সপ্রেশনটি "চরের 16-উপাদান অ্যারে" টাইপের হয় (সি তে; C ++ স্ট্রিংয়ের অক্ষরে অক্ষরের চরের অ্যারে হয়)। যাইহোক, কলটিতে strcpy(), উভয়ই ভাব প্রকাশের sizeofবা অপরূপ নয় &, সুতরাং তাদের প্রকারগুলি স্পষ্টতই "চরকে পয়েন্টারে" রূপান্তরিত হয় এবং তাদের মানগুলি প্রতিটিের প্রথম উপাদানটির ঠিকানায় সেট করা থাকে। যা strcpy()প্রাপ্ত হয় তা অ্যারে নয়, পয়েন্টারগুলি যেমন এর প্রোটোটাইপে দেখা যায়:

char *strcpy(char *dest, const char *src);

এটি অ্যারে পয়েন্টার হিসাবে একই জিনিস নয়। উদাহরণ স্বরূপ:

char a[80];
char *ptr_to_first_element = a;
char (*ptr_to_array)[80] = &a;

উভয় ptr_to_first_elementএবং ptr_to_arrayএকই মান আছে ; এর মূল ঠিকানা তবে এগুলি বিভিন্ন ধরণের এবং নীচে দেখানো হিসাবে আলাদাভাবে চিকিত্সা করা হয়:

a[i] == ptr_to_first_element[i] == (*ptr_to_array)[i] != *ptr_to_array[i] != ptr_to_array[i]

মনে রাখবেন যে অভিব্যক্তি a[i]হিসাবে ব্যাখ্যা করা হয় *(a+i)(যা শুধুমাত্র কাজ করে অ্যারের ধরনের একটি পয়েন্টার টাইপ রূপান্তরিত হয়) উভয় তাই হয়, a[i]এবং ptr_to_first_element[i]কাজ একই। অভিব্যক্তি (*ptr_to_array)[i]হিসাবে ব্যাখ্যা করা হয় *(*a+i)। এক্সপ্রেশনগুলি *ptr_to_array[i]এবং ptr_to_array[i]প্রসঙ্গের উপর নির্ভর করে সংকলক সতর্কতা বা ত্রুটিগুলিতে বাড়ে; আপনি যদি তাদের কাছে মূল্যায়নের প্রত্যাশা করছেন তবে তারা অবশ্যই ভুল কাজ করবে a[i]

sizeof a == sizeof *ptr_to_array == 80

আবার যখন একটি অ্যারে অপারেন্ড হয় তখন sizeofএটি পয়েন্টার ধরণের রূপান্তরিত হয় না।

sizeof *ptr_to_first_element == sizeof (char) == 1
sizeof ptr_to_first_element == sizeof (char *) == whatever the pointer size
                                                  is on your platform

ptr_to_first_element চরের জন্য একটি সাধারণ পয়েন্টার।


1
"This is a test" is of type "16-element array of char"একটি না "15-element array of char"? (দৈর্ঘ্য 14 + 1 \ 0 এর জন্য)
chux - মনিকা পুনঃস্থাপন

16

সি তে অ্যারেগুলির কোনও মূল্য নেই।

যেখানেই কোনও বস্তুর মান আশা করা যায় তবে বস্তুটি একটি অ্যারে হয়, প্রকারের পরিবর্তে এর প্রথম উপাদানটির ঠিকানা ব্যবহার করা হয় pointer to (type of array elements)

একটি ফাংশনে, সমস্ত পরামিতি মান দ্বারা পাস করা হয় (অ্যারেগুলি ব্যতিক্রম নয়)। আপনি যখন কোনও ক্রমে কোনও অ্যারে পাস করেন তখন এটি "পয়েন্টারে পরিণত হয়" (sic); যখন আপনি কোনও অ্যারের সাথে অন্য কোনও কিছুর সাথে তুলনা করেন, আবার এটি "পয়েন্টারে পরিণত হয়" (sic); ...

void foo(int arr[]);

ফাংশন ফু একটি অ্যারের মান আশা করে। তবে, সি তে অ্যারের কোনও মূল্য নেই! সুতরাং fooপরিবর্তে অ্যারের প্রথম উপাদান এর ঠিকানা পায়।

int arr[5];
int *ip = &(arr[1]);
if (arr == ip) { /* something; */ }

উপরের তুলনায়, arrএর কোনও মান নেই, সুতরাং এটি পয়েন্টার হয়ে যায়। এটি ইন পয়েন্টার হয়ে যায়। সেই পয়েন্টারটি ভেরিয়েবলের সাথে তুলনা করা যায় ip

অ্যারে ইনডেক্সিং সিনট্যাক্সে আপনি দেখতে অভ্যস্ত, আবার, অ্যারেরটি 'পয়েন্টারে ক্ষয়প্রাপ্ত'

arr[42];
/* same as *(arr + 42); */
/* same as *(&(arr[0]) + 42); */

কেবলমাত্র অ্যারে যখন পয়েন্টারটিতে ক্ষয় হয় না তখনই যখন এটি আকারের অপারেটরের অপারেন্ড হয় এবং & অপারেটর ('অপারেটরের ঠিকানা') হয়, বা একটি অক্ষর অ্যারে শুরু করার জন্য স্ট্রিং আক্ষরিক হিসাবে ব্যবহৃত হয়।


5
"অ্যারেগুলির কোনও মূল্য নেই" - এর অর্থ কী? অবশ্যই অ্যারেগুলির মান রয়েছে ... তারা বস্তু, আপনি পয়েন্টার পেতে পারেন এবং সি ++ এ তাদের উল্লেখ করতে পারেন ইত্যাদি
পাভেল মিনায়েভ

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

যাইহোক, আমি মনে করি একটি সামান্য অস্পষ্টতা রয়েছে: কোনও বস্তুর মূল্য এবং একটি অভিব্যক্তির মান (যেমন "" মূল্য ")। যদি পরের দিকটি ব্যাখ্যা করা হয়, তবে অবশ্যই একটি অ্যারের এক্সপ্রেশনটির একটি মান রয়েছে: এটির ফলে এটি কোনও ক্ষয় হওয়ার ফলে ফলাফলের দিকে যায় এবং এটি পয়েন্টার এক্সপ্রেশন। তবে যদি পূর্বের পদ্ধতিটি ব্যাখ্যা করা হয় তবে অবশ্যই কোনও অ্যারে অবজেক্টের জন্য কোনও কার্যকর অর্থ নেই।
জোহানেস স্কাউব -

1
একটি ছোট ফিক্স সহ বাক্যাংশের জন্য +1; অ্যারেগুলির জন্য এটি একটি ট্রিপলেট কেবল একটি দম্পতি [অবস্থান, টাইপ] নয়। অ্যারের ক্ষেত্রে তৃতীয় অবস্থানের জন্য আপনার মনে কি অন্য কিছু ছিল? আমি কিছু ভাবতে পারি না।
কিংবদন্তি

1
@ কিংবদন্তি 2 কে: আমি মনে করি যে আমি অ্যারেতে তৃতীয় অবস্থানটি ব্যবহার করেছি যাতে তাদের কেবল একটি দম্পতি থাকার বিশেষ কেস তৈরি না হয়। হয়তো [অবস্থান, প্রকার, শূন্যতা ] আরও ভাল হত।
পিএমজি

8

এটি যখন অ্যারে রট হয় এবং এর দিকে চিহ্নিত করা হয় ;-)

প্রকৃতপক্ষে, এটি ঠিক যে আপনি কোথাও একটি অ্যারে পাস করতে চান তবে পয়েন্টারটি তার পরিবর্তে পাস হয়েছে (কারণ কে আপনার জন্য নরক পুরো অ্যারেটি কেটে দেবে), লোকেরা বলে যে দরিদ্র অ্যারে পয়েন্টারে ক্ষয় হয়ে গেছে।


ভালো বলেছ. এমন কোনও চমৎকার অ্যারে কী হবে যা কোনও পয়েন্টার বা ক্ষয় থেকে রোধ করা একটির ক্ষয় হয় না? আপনি কি সি তে একটি উদাহরণ দিতে পারেন? ধন্যবাদ।
আনহেইলিগ

@ উনিহিলিগ, নিশ্চিতভাবেই, কেউ স্ট্রাকের মধ্যে একটি অ্যারে ভ্যাকুয়াম-প্যাক করতে পারে এবং স্ট্রাক্টটি পাস করতে পারে।
মাইকেল ক্রেলিন - হ্যাকার

আপনি "কাজ" বলতে কী বোঝায় তা নিশ্চিত নই। এটি অ্যারে অ্যাক্সেস করার অনুমতি দেওয়া হয় না, যদিও এটি প্রত্যাশিত হিসাবে কাজ করে যদি আপনি বাস্তবে যা ঘটে তা প্রত্যাশা করেন। সেই আচরণটি (যদিও, আবার সরকারীভাবে অপরিবর্তিত) সংরক্ষিত।
মাইকেল ক্রেলিন - হ্যাকার

ক্ষয় এমন অনেক পরিস্থিতিতেও ঘটে যা কোথাও অ্যারে পাস করে না (অন্যান্য উত্তর দ্বারা বর্ণিত)। উদাহরণস্বরূপ a + 1,।
এমএম

3

অ্যারের ক্ষয় হওয়ার অর্থ হ'ল, যখন কোনও ক্রিয়াকলাপের জন্য প্যারামিটার হিসাবে অ্যারেটি পাস করা হয়, তখন এটি পয়েন্টার হিসাবে ("ডেসে") একইরূপে আচরণ করা হয়।

void do_something(int *array) {
  // We don't know how big array is here, because it's decayed to a pointer.
  printf("%i\n", sizeof(array));  // always prints 4 on a 32-bit machine
}

int main (int argc, char **argv) {
    int a[10];
    int b[20];
    int *c;
    printf("%zu\n", sizeof(a)); //prints 40 on a 32-bit machine
    printf("%zu\n", sizeof(b)); //prints 80 on a 32-bit machine
    printf("%zu\n", sizeof(c)); //prints 4 on a 32-bit machine
    do_something(a);
    do_something(b);
    do_something(c);
}

উপরোক্ত দুটি জটিলতা বা ব্যতিক্রম রয়েছে।

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

void do_something(int array[][10])
{
    // We don't know how big the first dimension is.
}

int main(int argc, char *argv[]) {
    int a[5][10];
    int b[20][10];
    do_something(a);
    do_something(b);
    return 0;
}

দ্বিতীয়ত, সি ++ এ আপনি অ্যারেগুলির আকার হ্রাস করতে টেমপ্লেটগুলি ব্যবহার করতে পারেন। মাইক্রোসফ্ট এটি স্ট্রাইকপি_ এর মতো সিকিউর সিআরটি ফাংশনের সি ++ সংস্করণগুলির জন্য ব্যবহার করে এবং আপনি কোনও অ্যারের উপাদানগুলির সংখ্যা নির্ভরযোগ্যতার সাথে পেতে একই ধরণের কৌশল ব্যবহার করতে পারেন ।


1
ক্ষয় অন্যান্য অনেক পরিস্থিতিতে ঘটে, কেবল কোনও ফাংশনে অ্যারে পাস করে নয়।
এমএম

0

tl; dr: আপনি সংজ্ঞায়িত একটি অ্যারে ব্যবহার করার পরে, আপনি আসলে তার প্রথম উপাদানটির জন্য একটি পয়েন্টার ব্যবহার করবেন।

এভাবে:

  • আপনি যখন লিখবেন arr[idx]আপনি সত্যই বলছেন *(arr + idx)
  • ফাংশন কখনই অ্যারেগুলিকে প্যারামিটার হিসাবে কেবলমাত্র পয়েন্টার হিসাবে নেয় না, এমনকি আপনি যখন অ্যারে প্যারামিটারটি নির্দিষ্ট করেন তখনও।

এই নিয়মের ব্যতিক্রমগুলি বাছাই করুন:

  • আপনি এ এর ​​মধ্যে ফাংশনগুলিতে স্থির দৈর্ঘ্যের অ্যারেগুলি পাস করতে পারেন struct
  • sizeof() অ্যারের দ্বারা নেওয়া আকার দেয়, পয়েন্টারের আকার নয়।

0

আমি মনে করতে এত সাহসী হতে পারি যে ফাংশন আর্গুমেন্ট হিসাবে অ্যারে পাস করার জন্য চার (4) উপায় রয়েছে। এছাড়াও আপনার অনুমানের জন্য এখানে সংক্ষিপ্ত তবে কার্যকারী কোড রয়েছে।

#include <iostream>
#include <string>
#include <vector>
#include <cassert>

using namespace std;

// test data
// notice native array init with no copy aka "="
// not possible in C
 const char* specimen[]{ __TIME__, __DATE__, __TIMESTAMP__ };

// ONE
// simple, dangerous and useless
template<typename T>
void as_pointer(const T* array) { 
    // a pointer
    assert(array != nullptr); 
} ;

// TWO
// for above const T array[] means the same
// but and also , minimum array size indication might be given too
// this also does not stop the array decay into T *
// thus size information is lost
template<typename T>
void by_value_no_size(const T array[0xFF]) { 
    // decayed to a pointer
    assert( array != nullptr ); 
}

// THREE
// size information is preserved
// but pointer is asked for
template<typename T, size_t N>
void pointer_to_array(const T (*array)[N])
{
   // dealing with native pointer 
    assert( array != nullptr ); 
}

// FOUR
// no C equivalent
// array by reference
// size is preserved
template<typename T, size_t N>
void reference_to_array(const T (&array)[N])
{
    // array is not a pointer here
    // it is (almost) a container
    // most of the std:: lib algorithms 
    // do work on array reference, for example
    // range for requires std::begin() and std::end()
    // on the type passed as range to iterate over
    for (auto && elem : array )
    {
        cout << endl << elem ;
    }
}

int main()
{
     // ONE
     as_pointer(specimen);
     // TWO
     by_value_no_size(specimen);
     // THREE
     pointer_to_array(&specimen);
     // FOUR
     reference_to_array( specimen ) ;
}

আমি আরও ভাবতে পারি যে এটি সি ++ বনাম সি এর শ্রেষ্ঠত্ব দেখায় কমপক্ষে রেফারেন্স দ্বারা কোনও অ্যারে পাস করার ক্ষেত্রে (পাং উদ্দেশ্যে)।

অবশ্যই চূড়ান্ত বরাদ্দ, কোনও ব্যতিক্রম এবং কোনও স্টাড :: লিব ছাড়াই অত্যন্ত কঠোর প্রকল্প রয়েছে। সি ++ নেটিভ অ্যারে হ্যান্ডলিং হ'ল মিশন সমালোচনামূলক ভাষার বৈশিষ্ট্য one

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