ব্যাখ্যা সহ একটি উদাহরণ অন্তর্ভুক্ত করুন।
int *p;
একটি পূর্ণসংখ্যার একটি পয়েন্টার সংজ্ঞায়িত করবে, এবং *p
যে পয়েন্টার অবলম্বন করবে, অর্থাত্ এটি পি নির্দেশ করে যে তথ্যটি পুনরুদ্ধার করবে।
ব্যাখ্যা সহ একটি উদাহরণ অন্তর্ভুক্ত করুন।
int *p;
একটি পূর্ণসংখ্যার একটি পয়েন্টার সংজ্ঞায়িত করবে, এবং *p
যে পয়েন্টার অবলম্বন করবে, অর্থাত্ এটি পি নির্দেশ করে যে তথ্যটি পুনরুদ্ধার করবে।
উত্তর:
প্রক্রিয়াটির স্মৃতিতে দ্বিতীয় বাইট, 2 তৃতীয়, 3 চতুর্থ এবং এরকম 1 উল্লেখ করে একটি সংখ্যার মেমরি ঠিকানা সম্বলিত একটি পয়েন্টারটি কল্পনা করার জন্য এটি সাধারণত যথেষ্ট পরিমাণে সমাবেশ - আপনি অ্যাসেম্বলির প্রোগ্রামিং না করে ....
যখন আপনি মেমোরিতে যে ডেটা / মানটি অ্যাক্সেস করতে চান যা পয়েন্টারটি নির্দেশ করে - সেই সংখ্যাসূচক সূচী সহ ঠিকানার সামগ্রী - তখন আপনি পয়েন্টারটিকে অবলম্বন করেন।
সংকলক বা দোভাষীকে বলতে এখন বিভিন্ন কম্পিউটার ভাষার আলাদা আলাদা স্বরলিপি রয়েছে যা আপনি এখন পয়েন্ট-টু অবজেক্টের (বর্তমান) মানের প্রতি আগ্রহী - আমি সি এবং সি ++ এর নীচে ফোকাস করি।
সি হিসাবে বিবেচনা করুন, p
নীচে যেমন একটি পয়েন্টার দেওয়া ...
const char* p = "abc";
... টেক্সটুয়াল ডেটার সমাপ্তি বোঝাতে অক্ষরগুলিকে 'এ', 'বি', 'সি', এবং 0 বাইট ব্যবহার করার জন্য ব্যবহৃত সংখ্যার মান সহ চারটি বাইট স্মৃতিতে কোথাও সংরক্ষণ করা হয় এবং এর সংখ্যার ঠিকানা তথ্য সংরক্ষণ করা হয় p
। মেমরিতে সি এনকোড পাঠ্য এইভাবে ASCIIZ হিসাবে পরিচিত ।
উদাহরণস্বরূপ, যদি স্ট্রিংটি 0x1000 ঠিকানার ঠিকানা এবং 0x2000 এ p
32-বিট পয়েন্টার হতে পারে তবে মেমরির সামগ্রীটি হবে:
Memory Address (hex) Variable name Contents
1000 'a' == 97 (ASCII)
1001 'b' == 98
1002 'c' == 99
1003 0
...
2000-2003 p 1000 hex
নোট ঠিকানা 0x1000 জন্য কোন পরিবর্তনশীল নাম / আইডেন্টিফায়ার আছে, যে, কিন্তু আমরা পরোক্ষভাবে একটি পয়েন্টার এটির ঠিকানা সংরক্ষণকারী ব্যবহার আক্ষরিক স্ট্রিং উল্লেখ করতে পারেন: p
।
বর্ণচিহ্নগুলি p
নির্দেশ করে, আমরা p
এই স্বরলিপিগুলির মধ্যে একটি (আবার, সি এর জন্য) ব্যবহার করে অবজ্ঞা করি :
assert(*p == 'a'); // The first character at address p will be 'a'
assert(p[1] == 'b'); // p[1] actually dereferences a pointer created by adding
// p and 1 times the size of the things to which p points:
// In this case they're char which are 1 byte in C...
assert(*(p + 1) == 'b'); // Another notation for p[1]
আপনি পয়েন্টারগুলিকে পয়েন্ট-টু ডেটা দিয়েও যেতে পারেন, যেতে যেতে সেগুলি অবলম্বন করে:
++p; // Increment p so it's now 0x1001
assert(*p == 'b'); // p == 0x1001 which is where the 'b' is...
আপনার কাছে যদি এমন কিছু ডেটা থাকে যাতে লিখিত হতে পারে তবে আপনি এই জাতীয় জিনিসগুলি করতে পারেন:
int x = 2;
int* p_x = &x; // Put the address of the x variable into the pointer p_x
*p_x = 4; // Change the memory at the address in p_x to be 4
assert(x == 4); // Check x is now 4
উপরে, আপনি অবশ্যই সংকলন সময়ে জেনে থাকতে পারেন যে আপনাকে একটি পরিবর্তনশীল নামক দরকার হবে x
, এবং কোডটি সংকলকটিকে এটি কোথায় সংরক্ষণ করা উচিত সে বিষয়ে ব্যবস্থা করতে বলে, যাতে ঠিকানাটি উপলব্ধ হবে তা নিশ্চিত করে &x
।
সি-তে, যদি আপনার কাছে এমন একটি ভেরিয়েবল থাকে যা ডেটা সদস্যদের সাথে কোনও কাঠামোর পয়েন্টার হয় তবে আপনি সেই সদস্যদের ->
ডিফেরেন্সিং অপারেটর ব্যবহার করে অ্যাক্সেস করতে পারেন :
typedef struct X { int i_; double d_; } X;
X x;
X* p = &x;
p->d_ = 3.14159; // Dereference and access data member x.d_
(*p).d_ *= -1; // Another equivalent notation for accessing x.d_
একটি পয়েন্টার ব্যবহার করার জন্য, একটি কম্পিউটার প্রোগ্রামকে যে ধরণের ডেটা নির্দেশ করা হচ্ছে সে সম্পর্কেও কিছুটা অন্তর্দৃষ্টি প্রয়োজন - যদি সেই ডেটা টাইপটি উপস্থাপনের জন্য একাধিক বাইটের প্রয়োজন হয় তবে পয়েন্টারটি সাধারণত ডেটাতে সর্বনিম্ন-সংখ্যাযুক্ত বাইটকে নির্দেশ করে।
সুতরাং, কিছুটা আরও জটিল উদাহরণের দিকে তাকানো:
double sizes[] = { 10.3, 13.4, 11.2, 19.4 };
double* p = sizes;
assert(p[0] == 10.3); // Knows to look at all the bytes in the first double value
assert(p[1] == 13.4); // Actually looks at bytes from address p + 1 * sizeof(double)
// (sizeof(double) is almost always eight bytes)
++p; // Advance p by sizeof(double)
assert(*p == 13.4); // The double at memory beginning at address p has value 13.4
*(p + 2) = 29.8; // Change sizes[3] from 19.4 to 29.8
// Note earlier ++p and + 2 here => sizes[3]
কখনও কখনও আপনি জানেন না যে আপনার প্রোগ্রামটি চলমান অবধি আপনার কতটুকু স্মৃতি দরকার এবং এটিতে কোন ডেটা নিক্ষেপ করা হয় তা না দেখে ... তারপরে আপনি ব্যবহার করে মেমরিটিকে গতিশীলভাবে বরাদ্দ করতে পারেন malloc
। ঠিকানাটি কোনও পয়েন্টারে সঞ্চয় করা সাধারণ অভ্যাস ...
int* p = (int*)malloc(sizeof(int)); // Get some memory somewhere...
*p = 10; // Dereference the pointer to the memory, then write a value in
fn(*p); // Call a function, passing it the value at address p
(*p) += 3; // Change the value, adding 3 to it
free(p); // Release the memory back to the heap allocation library
সি ++ এ, মেমরির বরাদ্দ সাধারণত new
অপারেটরের সাথে করা হয় , এবং এর সাথে ডিওলোকেশন delete
:
int* p = new int(10); // Memory for one int with initial value 10
delete p;
p = new int[10]; // Memory for ten ints with unspecified initial value
delete[] p;
p = new int[10](); // Memory for ten ints that are value initialised (to 0)
delete[] p;
আরও দেখুন সি ++ স্মার্ট পয়েন্টার থেকে কম।
প্রায়শই কোনও পয়েন্টারটি কেবলমাত্র যেখানে কিছু ডেটা বা বাফার মেমরিতে উপস্থিত থাকে তার একমাত্র ইঙ্গিত হতে পারে। যদি সেই ডেটা / বাফারটির চলমান ব্যবহারের প্রয়োজন হয়, বা কল করার free()
বা delete
মেমরি ফাঁস করা এড়াতে দক্ষতার প্রয়োজন হয় তবে প্রোগ্রামারকে অবশ্যই পয়েন্টারের অনুলিপিটিতে কাজ করতে হবে ...
const char* p = asprintf("name: %s", name); // Common but non-Standard printf-on-heap
// Replace non-printable characters with underscores....
for (const char* q = p; *q; ++q)
if (!isprint(*q))
*q = '_';
printf("%s\n", p); // Only q was modified
free(p);
... বা সাবধানে যেকোন পরিবর্তনের বিপরীতে অর্কেস্ট্রেট ...
const size_t n = ...;
p += n;
...
p -= n; // Restore earlier value...
free(p);
সি ++ এ, পয়েন্টারগুলি সংরক্ষণ এবং পরিচালনা করতে স্মার্ট পয়েন্টার অবজেক্টগুলি ব্যবহার করার সর্বোত্তম অনুশীলন , স্মার্ট পয়েন্টারগুলির ডেস্ট্রাক্টর চললে স্বয়ংক্রিয়ভাবে সেগুলি হ্রাস করে। যেহেতু সি ++ 11 স্ট্যান্ডার্ড লাইব্রেরি দুটি সরবরাহ করে, unique_ptr
যখন কোনও বরাদ্দকৃত সামগ্রীর জন্য যখন একক মালিক থাকে ...
{
std::unique_ptr<T> p{new T(42, "meaning")};
call_a_function(p);
// The function above might throw, so delete here is unreliable, but...
} // p's destructor's guaranteed to run "here", calling delete
... এবং shared_ptr
ভাগ মালিকানার জন্য ( রেফারেন্স গণনা ব্যবহার করে ) ...
{
auto p = std::make_shared<T>(3.14, "pi");
number_storage1.may_add(p); // Might copy p into its container
number_storage2.may_add(p); // Might copy p into its container } // p's destructor will only delete the T if neither may_add copied it
সি, NULL
এবং 0
- এবং অতিরিক্তে সি ++ nullptr
- এ নির্দেশ করতে ব্যবহার করা যেতে পারে যে কোনও পয়েন্টার বর্তমানে কোনও ভেরিয়েবলের মেমরি ঠিকানা রাখে না, এবং এটি পয়েন্টার গাণিতিকের ক্ষেত্রে অবনমিত বা ব্যবহার করা উচিত নয়। উদাহরণ স্বরূপ:
const char* p_filename = NULL; // Or "= 0", or "= nullptr" in C++
int c;
while ((c = getopt(argc, argv, "f:")) != -1)
switch (c) {
case f: p_filename = optarg; break;
}
if (p_filename) // Only NULL converts to false
... // Only get here if -f flag specified
সি এবং সি ++-তে, যেমন অন্তর্নির্মিত সংখ্যাসূচক প্রকারগুলি অগত্যা ডিফল্ট হয় 0
না বা bools
হয় না false
, পয়েন্টার সর্বদা সেট থাকে না NULL
। এগুলি সমস্ত 0 / ভুয়া / NULL এ সেট করা হয় যখন তারা static
স্থায়ী বস্তু বা তাদের ঘাঁটিগুলির প্রত্যক্ষ বা অপ্রত্যক্ষ সদস্য ভেরিয়েবল হয় বা শূন্য সূচনা (যেমন new T();
এবং new T(x, y, z);
পয়েন্টার সহ টি এর সদস্যদের উপর শূন্য-আরম্ভকরণ সম্পাদন করে) new T;
না).
উপরন্তু, যখন আপনি নির্ধারণ 0
, NULL
এবং nullptr
একটি পয়েন্টার পয়েন্টার বিট না অগত্যা সব রিসেট আছেন: পয়েন্টার হার্ডওয়্যার পর্যায়ে থাকতে পারে না "0", অথবা আপনার ভার্চুয়াল অ্যাড্রেস স্পেস ঠিকানা 0 পড়ুন। কম্পাইলার দোকান কিছু অন্য সেখানে যদি এটা করিবার কারণ থাকে অনুমতি দেওয়া হয়, কিন্তু যাই হোক না কেন এটা আছে - আপনি বরাবর আসা এবং পয়েন্টার তুলনা 0
, NULL
, nullptr
বা অন্য পয়েন্টার সেই কোন বরাদ্দ করা হয়েছিল, আশানুরূপ তুলনা আবশ্যক হবে। সুতরাং, সংকলক স্তরে উত্স কোডের নীচে, "এনইউএল" হ'ল সি এবং সি ++ ভাষায় সম্ভবত "জাদু" হতে পারে ...
আরও কঠোরভাবে, আরম্ভিক পয়েন্টারগুলি বিট-প্যাটার্ন সংরক্ষণ করে থাকে একটি NULL
বা একটি (প্রায়শই ভার্চুয়াল ) মেমরি ঠিকানা।
প্রক্রিয়াটির সম্পূর্ণ ভার্চুয়াল ঠিকানা জায়গাতে এটি একটি সংখ্যাসূচক অফসেট যেখানে সহজ ক্ষেত্রে; আরও জটিল ক্ষেত্রে পয়েন্টারটি নির্দিষ্ট কিছু মেমরি অঞ্চলের সাথে সম্পর্কিত হতে পারে, যা সিপিইউ সিপিইউ "সেগমেন্ট" রেজিস্টারের ভিত্তিতে বা বিট-প্যাটার্নে এনকোডেড সেগমেন্ট আইডির কিছু উপায়ে এবং / বা তার উপর নির্ভর করে বিভিন্ন জায়গায় সন্ধান করতে পারে ঠিকানা ব্যবহার করে মেশিন কোড নির্দেশাবলী।
উদাহরণস্বরূপ, একটি ভেরিয়েবলের int*
দিকে ইঙ্গিত করার জন্য একটি সঠিকভাবে আরম্ভ করা int
- float*
"জিপিইউ" মেমরিটিতে অ্যাক্সেস মেমরিটি int
ভেরিয়েবল যেখানে মেমরি থেকে একেবারে আলাদা , তারপরে একবার কাস্ট করা হয় এবং একটি ফাংশন পয়েন্টার হিসাবে ব্যবহৃত হয় এটি আরও নির্দেশ করতে পারে প্রোগ্রামটির জন্য স্বতন্ত্র মেমরি হোল্ডিং মেশিনটি অপকড করে ( int*
কার্যকরভাবে একটি এলোমেলো, এই অন্যান্য মেমরি অঞ্চলে অবৈধ পয়েন্টারটির সংখ্যাসূচক মান সহ )।
সি এবং সি ++ এর মতো 3GL প্রোগ্রামিং ল্যাঙ্গুয়েজে এই জটিলতাগুলি আড়াল করার প্রবণতা রয়েছে যেমন:
যদি সংকলক আপনাকে কোনও চলক বা ফাংশনটির জন্য একটি পয়েন্টার দেয়, আপনি এটিকে অবাধে নির্বিঘ্ন করতে পারেন (যতক্ষণ না এর মধ্যে ভেরিয়েবলটি ধ্বংস হয় না / ততক্ষণ অবনতি হয় না) এবং এটি সংকলকের সমস্যা যেমন উদাহরণস্বরূপ কোনও নির্দিষ্ট সিপিইউ বিভাগের রেজিস্ট্রার পূর্বে পুনরুদ্ধার করা দরকার, বা একটি স্বতন্ত্র মেশিন কোড নির্দেশ ব্যবহার করা হয়
আপনি যদি অ্যারেতে কোনও উপাদানের একটি পয়েন্টার পেয়ে থাকেন তবে আপনি অ্যারের অন্য কোথাও যেতে পয়েন্টার পাটিগণিত ব্যবহার করতে পারেন, বা অ্যারের এক-গত-শেষের ঠিকানা তৈরি করতে পারেন যা উপাদানগুলির সাথে অন্য পয়েন্টারের সাথে তুলনা করার জন্য আইনী অ্যারেতে (বা যা একইভাবে পয়েন্টার গাণিতিক দ্বারা একই এক-অতীত-শেষের মানটিতে সরানো হয়েছে); আবার সি এবং সি ++ এ, এটি "ঠিক কাজ করে" তা নিশ্চিত করার জন্য এটি সংকলকের উপর নির্ভর করে
নির্দিষ্ট ওএস ফাংশন, যেমন ভাগ করা মেমরি ম্যাপিং, আপনাকে পয়েন্টার দিতে পারে এবং তারা ঠিকানার ঠিকানার মধ্যে "কাজ করবে" যা তাদের জন্য অর্থবোধ করে makes
আইনী পয়েন্টারগুলিকে এই সীমানার বাইরে চলে যাওয়ার চেষ্টা বা পয়েন্টারগুলিতে স্বেচ্ছাসেবী সংখ্যার কাস্ট করা বা অসম্পূর্ণ প্রকারে কাস্ট পয়েন্টার ব্যবহার করা সাধারণত অনির্ধারিত আচরণ করে , তাই উচ্চ স্তরের লাইব্রেরি এবং অ্যাপ্লিকেশনগুলিতে এড়ানো উচিত, তবে ওএস, ডিভাইস ড্রাইভার ইত্যাদির কোড সি বা সি ++ স্ট্যান্ডার্ড দ্বারা অপরিবর্তিত আচরণের উপর নির্ভর করতে হতে পারে, যা তাদের নির্দিষ্ট প্রয়োগ বা হার্ডওয়্যার দ্বারা সুনির্দিষ্টভাবে সংজ্ঞায়িত।
p[1]
এবং *(p + 1)
অভিন্ন ? অর্থাৎ, একই নির্দেশাবলী তৈরি করে p[1]
এবং *(p + 1)
উত্পন্ন করে?
p
কেবল 2000: আপনার যদি অন্য কোনও পয়েন্টার থাকে p
তবে এটির চার বা আট বাইটে 2000 সঞ্চয় করতে হবে। আশা করি এইটি কাজ করবে! চিয়ার্স।
u
একটি অ্যারে থাকে arr
তবে জিসিসি এবং বিড়াল উভয়ই স্বীকৃতি জানাতে u.arr[i]
পারে যে লভালু একই ইউনিয়নে অন্যান্য ইউনিয়নের সদস্যদের মতো অ্যাক্সেস করতে পারে তবে স্বীকৃতি দেবে না যে লভালু এটি *(u.arr+i)
করতে পারে। আমি নিশ্চিত নই যে এই সংকলকগুলির লেখকরা মনে করেন যে উত্তরোত্তর ইউবিকে আহ্বান জানায়, বা প্রাক্তন ইউবিকে ডাকেন তবে তাদের যেভাবেই এটি কার্যকরভাবে প্রক্রিয়া করা উচিত, তবে তারা স্পষ্টতই দুটি অভিব্যক্তিটি ভিন্ন হিসাবে দেখেন।
পয়েন্টারকে ডিফার করা মানে পয়েন্টার দ্বারা চিহ্নিত মেমরির স্থানে থাকা মানটি পাওয়া getting অপারেটর * এটি করতে ব্যবহৃত হয় এবং তাকে ডেরেফারেন্সিং অপারেটর বলা হয়।
int a = 10;
int* ptr = &a;
printf("%d", *ptr); // With *ptr I'm dereferencing the pointer.
// Which means, I am asking the value pointed at by the pointer.
// ptr is pointing to the location in memory of the variable a.
// In a's location, we have 10. So, dereferencing gives this value.
// Since we have indirect control over a's location, we can modify its content using the pointer. This is an indirect way to access a.
*ptr = 20; // Now a's content is no longer 10, and has been modified to 20.
[]
একটি পয়েন্টারকেও ( a[b]
মানে সংজ্ঞায়িত করা হয় *(a + b)
) অবজ্ঞাপন করে ।
একটি পয়েন্টার একটি মানের জন্য "রেফারেন্স" .. অনেকটা লাইব্রেরির কল নম্বর যেমন কোনও বইয়ের একটি রেফারেন্স। কলটি নাম্বারটি "ডিফেরেন্সিং" শারীরিকভাবে চলছে এবং সেই বইটি পুনরুদ্ধার করছে।
int a=4 ;
int *pA = &a ;
printf( "The REFERENCE/call number for the variable `a` is %p\n", pA ) ;
// The * causes pA to DEREFERENCE... `a` via "callnumber" `pA`.
printf( "%d\n", *pA ) ; // prints 4..
যদি বইটি না থাকে তবে গ্রন্থাগারিক চিৎকার শুরু করে, গ্রন্থাগারটি বন্ধ করে দেয় এবং দু'জন লোক কোনও বইয়ের সন্ধানের জন্য অনুসন্ধান করতে প্রস্তুত হয় যা সেখানে নেই।
সহজ কথায়, ডেরেফারিংয়ের অর্থ একটি নির্দিষ্ট মেমোরি অবস্থান থেকে মানটি অ্যাক্সেস করা যার বিরুদ্ধে সেই পয়েন্টারটি নির্দেশ করছে।
পয়েন্টার বেসিকস থেকে কোড এবং ব্যাখ্যা :
বিন্যাস অপারেশনটি পয়েন্টারে শুরু হয় এবং এর পয়েন্টটি অ্যাক্সেস করতে তার তীরটিকে অনুসরণ করে। লক্ষ্য হতে পারে পয়েন্টি স্টেটের দিকে নজর দেওয়া বা পয়েন্টি স্টেট পরিবর্তন করা। পয়েন্টারের উপর ডেরিফারেন্স অপারেশনটি কেবল তখনই কাজ করে যদি পয়েন্টারের কোনও পয়েন্টি থাকে - পয়েন্টটি বরাদ্দ করতে হবে এবং পয়েন্টারটি অবশ্যই এটিতে নির্দেশ করতে হবে। পয়েন্টার কোডে সর্বাধিক সাধারণ ত্রুটি পয়েন্টটি সেট আপ করতে ভুলে যাওয়া। কোডটিতে ত্রুটির কারণে সর্বাধিক সাধারণ রানটাইম ক্র্যাশ হ'ল একটি ব্যর্থ ডিरेফারেশন অপারেশন। জাভাতে ভুল সময়সীমাটি রানটাইম সিস্টেমের মাধ্যমে নম্রভাবে পতাকাঙ্কিত করা হবে। সংকলিত ভাষায় যেমন সি, সি ++, এবং পাসকালে, ভুল অবলম্বন কখনও কখনও ক্র্যাশ হয়ে যায় এবং অন্য সময় স্মৃতিটিকে কিছু সূক্ষ্ম, এলোমেলোভাবে দূষিত করে।
void main() {
int* x; // Allocate the pointer x
x = malloc(sizeof(int)); // Allocate an int pointee,
// and set x to point to it
*x = 42; // Dereference x to store 42 in its pointee
}
আমি মনে করি পূর্ববর্তী সমস্ত উত্তরগুলি ভুল, কারণ তারা জানিয়েছে যে ডেরেফারিংয়ের অর্থ আসল মান অ্যাক্সেস করা। উইকিপিডিয়া পরিবর্তে সঠিক সংজ্ঞা দেয়: https://en.wikedia.org/wiki/Dereferences_operator
এটি একটি পয়েন্টার ভেরিয়েবলের উপর পরিচালিত হয় এবং পয়েন্টার ঠিকানায় মানের সমান এল-মান প্রদান করে। একে পয়েন্টারটিকে "ডেরেফারেন্সিং" বলা হয়।
এটি বলেছে, আমরা যে বিন্দুতে নির্দেশ করে তাতে অ্যাক্সেস না করেই আমরা পয়েন্টারটিকে অবহেলা করতে পারি। উদাহরণ স্বরূপ:
char *p = NULL;
*p;
আমরা NUL পয়েন্টারটির মান অ্যাক্সেস না করেই তাকে অবহিত করেছি। বা আমরা করতে পারি:
p1 = &(*p);
sz = sizeof(*p);
আবার, ডিফেরেন্সিং, কিন্তু কখনই মান অ্যাক্সেস করা যায় না। এই জাতীয় কোড ক্রাশ হবে না: আপনি যখন অবৈধ পয়েন্টার দিয়ে ডেটা অ্যাক্সেস করেন তখন ক্র্যাশ ঘটে happens তবে, দুর্ভাগ্যক্রমে, মান অনুযায়ী, একটি অবৈধ পয়েন্টারকে ডিফারেন্স করা একটি অপরিজ্ঞাত আচরণ (কয়েকটি ব্যতিক্রম সহ), এমনকি যদি আপনি প্রকৃত ডেটা স্পর্শ করার চেষ্টা না করেন তবেও।
সংক্ষেপে: পয়েন্টারটিকে ডিফারেন্স করার অর্থ এটিতে ডেরিফারেন্স অপারেটর প্রয়োগ করা। সেই অপারেটর আপনার ভবিষ্যতের ব্যবহারের জন্য কেবলমাত্র একটি এল-মান প্রদান করে।
*p;
অপরিবর্তিত আচরণের কারণ। যদিও আপনি সঠিক যে dereferencing মান অ্যাক্সেস না হয় SE প্রতি , কোড *p;
আছে এক্সেস মান।