পয়েন্টার থেকে পয়েন্টার স্পষ্টতা


142

আমি এই টিউটোরিয়ালটি অনুসরণ করছিলাম কীভাবে পয়েন্টারটিতে পয়েন্টার কাজ করে।

প্রাসঙ্গিক প্যাসেজটি উদ্ধৃত করি:


    int i = 5, j = 6, k = 7;
    int *ip1 = &i, *ip2 = &j;

এখন আমরা সেট করতে পারি

    int **ipp = &ip1;

এবং ippপয়েন্ট ip1যা পয়েন্ট i*ippহয় ip1, এবং **ippহয় i, বা 5. আমরা পরিস্থিতিটি চিত্রিত করতে পারি, আমাদের পরিচিত বাক্স এবং তীর চিহ্নটির সাথে এটির মতো:

এখানে চিত্র বর্ণনা লিখুন

তাহলে যদি আমরা বলি

    *ipp = ip2;

এর একটি অনুলিপি রাখতে আমরা নির্দেশিত পয়েন্টারটি ipp(যা ip1) নির্দেশকটি পরিবর্তন করেছি ip2, যাতে এটি ( ip1) এখন পয়েন্ট করে j:

এখানে চিত্র বর্ণনা লিখুন


আমার প্রশ্ন হ'ল দ্বিতীয় ছবিতে কেন ippএখনও নির্দেশ করা হচ্ছে ip1কিন্তু নয় ip2?


6
দয়া করে ippসংজ্ঞা দেওয়ার সময় এর ধরণ যুক্ত করুন , সুতরাং আপনার প্রশ্নটি সম্পূর্ণ হয়ে গেছে ;-)
zmo

1
কারণ ippনির্দেশিত ip1তাই *ipp = ip2হিসাবে একইip1 = ip2
Grijesh চৌহান

1
আমরা দয়া করে বিন্দু টাইপ থেকে অনেক দূরে asteriks লেখা বন্ধ করতে পারেন? int **ippএর চেয়ে অনেক কম স্বজ্ঞাত int** ipp, বিশেষত যখন **ippপ্রকারের ঘোষণার বাইরে সম্পূর্ণ আলাদা জিনিস।
দারখোগ

4
@ দারখোগ int **ippআমার কাছে বেশ স্বজ্ঞাত বলে মনে হচ্ছে। এর অর্থ, আমি **ippএকটি তৈরি করছি int। কোনটা সত্য.
ithisa

2
@ user54609 অর্থ এবং বাদে ব্যক্তিগত জন্য intuitiveness, এই বিবেচনা করুন: ধরণ ippহয় int**, তাই শুধু লেখার int**পরিবর্তে ঐন্দ্রজালিক " impডি-রেফারেন্স কোন int" সমঝোতা
মনু 343726

উত্তর:


143

নির্দেশক সাদৃশ্য সম্পর্কে এক সেকেন্ডের জন্য ভুলে যান। একটি পয়েন্টারটিতে যা রয়েছে তা হ'ল একটি মেমরি ঠিকানা। এটি &হ'ল "ঠিকানা" অপারেটর - অর্থাৎ এটি কোনও বস্তুর স্মৃতিতে ঠিকানাটি ফেরত দেয়। *অপারেটর আপনি বস্তুর দেয় একটি পয়েন্টার, একটি পয়েন্টার একটি ঠিকানা ধারণকারী দেওয়া অর্থাত বোঝায়, এটা যে মেমরি ঠিকানায় বস্তুর ফেরৎ। সুতরাং যখন আপনি কি *ipp = ip2, কী করছ হয় *ippঅনুষ্ঠিত ঠিকানায় বস্তুর পেতে ippযা ip1এবং তারপর নির্ধারিত ip1মান সঞ্চিত ip2যার ঠিকানা, j

কেবল
& -> ঠিকানা
*-> মান


14
& এবং * কখনও এত সহজ ছিল না
রায়

7
আমি বিশ্বাস করি যে বিভ্রান্তির মূল উত্স * অপারেটরের অস্পষ্টতার কারণে, যা পরিবর্তনশীল ঘোষণার সময় এটি চিহ্নিত করতে ব্যবহৃত হয় যে ভেরিয়েবলটি আসলে একটি নির্দিষ্ট ডেটা ধরণের নির্দেশক। তবে, অন্যদিকে, এটি পয়েন্টার (ডিসিফারেন্সিং অপারেটর) দ্বারা চিহ্নিত ভ্যারিয়েবলের সামগ্রীগুলি অ্যাক্সেস করতে বিবৃতিতেও ব্যবহৃত হয়।
লুকাস এ

43

কারণ আপনি দ্বারা প্রতি ইঙ্গিত মান পরিবর্তন ippনা মান ipp। সুতরাং, ippএখনও ip1(মান ipp) নির্দেশ করে, ip1এর মান এখন ip2'এর মান হিসাবে একই , তাই তারা উভয়ই নির্দেশ করে j

এই:

*ipp = ip2;

হিসাবে একই:

ip1 = ip2;

11
int *ip1 = &iএবং এর মধ্যে পার্থক্যটি উল্লেখ করার উপযুক্ত হতে পারে *ipp = ip2;, উদাহরণস্বরূপ আপনি যদি intপ্রথম বিবৃতিটি থেকে অপসারণ করেন তবে অ্যাসাইনমেন্টগুলি খুব একইরকম দেখায়, তবে *দুটি ক্ষেত্রে খুব আলাদা কিছু করছে।
ক্রোম্যান

22

সি ট্যাগের প্রথম দিকের প্রশ্নের মতো, প্রথম নীতিতে ফিরে এই প্রশ্নের উত্তর দেওয়া যেতে পারে:

  • পয়েন্টারটি এক ধরণের মান।
  • একটি ভেরিয়েবলের একটি মান থাকে।
  • &অপারেটর একটি পয়েন্টার মধ্যে একটি পরিবর্তনশীল সক্রিয়।
  • *অপারেটর একটি পরিবর্তনশীল মধ্যে একটি পয়েন্টার সক্রিয়।

(প্রযুক্তিগতভাবে আমার "ভেরিয়েবল" এর পরিবর্তে "লভ্যালু" বলা উচিত, তবে আমি মনে করি যে পরিবর্তনীয় সঞ্চয়স্থানের অবস্থানগুলি "ভেরিয়েবল" হিসাবে বর্ণনা করা আরও স্পষ্ট।

সুতরাং আমাদের ভেরিয়েবল আছে:

int i = 5, j = 6;
int *ip1 = &i, *ip2 = &j;

চলকটিতে একটি পয়েন্টার ip1 রয়েছে&অপারেটর সক্রিয় iএকটি পয়েন্টার মধ্যে এবং যে পয়েন্টার মান নির্ধারিত হয় ip1। সুতরাং একটি পয়েন্টার ip1 রয়েছেi

চলকটিতে একটি পয়েন্টার ip2 রয়েছে&অপারেটর সক্রিয় jএকটি পয়েন্টার মধ্যে এবং যে পয়েন্টার নির্ধারিত হয় ip2। সুতরাং একটি পয়েন্টার ip2 রয়েছেj

int **ipp = &ip1;

চলকটিতে ippএকটি পয়েন্টার রয়েছে। &অপারেটর পরিবর্তনশীল সক্রিয় ip1একটি পয়েন্টার মধ্যে এবং যে পয়েন্টার মান নির্ধারিত হয় ipp। সুতরাং ippএকটি পয়েন্টার রয়েছে ip1

চলুন এখন পর্যন্ত গল্পটি সংক্ষিপ্ত করি:

  • i 5 রয়েছে
  • j 6 রয়েছে
  • ip1"পয়েন্টার টু i" রয়েছে
  • ip2"পয়েন্টার টু j" রয়েছে
  • ipp"পয়েন্টার টু ip1" রয়েছে

এখন আমরা বলি

*ipp = ip2;

*অপারেটর একটি পরিবর্তনশীল মধ্যে একটি পয়েন্টার ফিরে সক্রিয়। আমরা এর মান আনব ipp, যা "পয়েন্টার ip1এবং এটি একটি ভেরিয়েবলে রূপান্তরিত করে। কোন পরিবর্তনশীল? ip1অবশ্যই!

সুতরাং এটি কেবল বলার অন্য একটি উপায়

ip1 = ip2;

সুতরাং আমরা এর মান আনা ip2। এটা কি? "নির্দেশক j"। আমরা সেই পয়েন্টারের মান নির্ধারণ করি ip1, সুতরাং ip1এখন "পয়েন্টার j"

আমরা কেবল একটি জিনিস পরিবর্তন করেছি: এর মান ip1:

  • i 5 রয়েছে
  • j 6 রয়েছে
  • ip1"পয়েন্টার টু j" রয়েছে
  • ip2"পয়েন্টার টু j" রয়েছে
  • ipp"পয়েন্টার টু ip1" রয়েছে

কেন ippএখনও নির্দেশ করে ip1এবং না ip2?

আপনি যখন এটি নির্ধারণ করেন তখন একটি পরিবর্তনশীল পরিবর্তন হয়। অ্যাসাইনমেন্ট গণনা; অ্যাসাইনমেন্টের চেয়ে ভেরিয়েবলের চেয়ে বেশি পরিবর্তন হতে পারে না! আপনি বরাদ্দ দ্বারা শুরু i, j, ip1, ip2এবং ipp। আপনি তারপরে নিযুক্ত হন *ipp, যা আমরা দেখেছি এর অর্থ "অর্পণ করা ip1" সমান । যেহেতু আপনি ippদ্বিতীয় বার দায়িত্ব অর্পণ করেন নি, এটি পরিবর্তন হয়নি!

আপনি যদি পরিবর্তন ippকরতে চান তবে আপনাকে অবশ্যই এই নিয়োগ করতে হবে ipp:

ipp = &ip2;

এই ক্ষেত্রে.


21

আশা করি কোডের এই অংশটি সাহায্য করতে পারে।

#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
    int i = 5, j = 6, k = 7;
    int *ip1 = &i, *ip2 = &j;
    int** ipp = &ip1;
    printf("address of value i: %p\n", &i);
    printf("address of value j: %p\n", &j);
    printf("value ip1: %p\n", ip1);
    printf("value ip2: %p\n", ip2);
    printf("value ipp: %p\n", ipp);
    printf("address value of ipp: %p\n", *ipp);
    printf("value of address value of ipp: %d\n", **ipp);
    *ipp = ip2;
    printf("value ipp: %p\n", ipp);
    printf("address value of ipp: %p\n", *ipp);
    printf("value of address value of ipp: %d\n", **ipp);
}

এটি ফলাফল:

এখানে চিত্র বর্ণনা লিখুন


12

আমার খুব ব্যক্তিগত মতামতটি হ'ল তীরগুলি সহ ছবিগুলি এইভাবে নির্দেশ করছে বা এটি পয়েন্টারগুলিকে বোঝা আরও শক্ত করে তোলে। এটি তাদের কিছু বিমূর্ত, রহস্যময় সত্তার মতো করে তোলে। তারা না.

আপনার কম্পিউটারে থাকা সমস্ত কিছুর মতো পয়েন্টারও সংখ্যা । "পয়েন্টার" নামটি "ঠিকানা সহ একটি ভেরিয়েবল" বলার অভিনব উপায়।

অতএব, কম্পিউটার আসলে কীভাবে কাজ করে তা ব্যাখ্যা করে আমার চারপাশে জিনিসগুলি আলোড়িত করা যাক।

আমাদের একটি আছে int, এর নাম iএবং মান রয়েছে This এটি মেমরিতে সঞ্চয় করা হয়। স্মৃতিতে সঞ্চিত সমস্ত কিছুর মতো এটির একটি ঠিকানা প্রয়োজন, বা আমরা এটি সন্ধান করতে পারব না। আসুন iঠিকানা 0x12345678 এ শেষ হতে দেয় এবং এর j6 নম্বর সহ বন্ধুটি এর ঠিক পরে শেষ হয়। একটি 32-বিট সিপিইউ ধরে নেওয়া যেখানে int 4 বাইট এবং পয়েন্টার 4 বাইট হয়, তারপরে ভেরিয়েবলগুলি শারীরিক স্মৃতিতে এইভাবে সংরক্ষণ করা হয়:

Address     Data           Meaning
0x12345678  00 00 00 05    // The variable i
0x1234567C  00 00 00 06    // The variable j

এখন আমরা এই ভেরিয়েবলগুলিতে নির্দেশ করতে চাই। আমরা int এর জন্য একটি পয়েন্টার তৈরি করি int* ip1, এবং একটি int* ip2। কম্পিউটারের সমস্ত কিছুর মতো, এই পয়েন্টার ভেরিয়েবলগুলি স্মৃতিতেও কোথাও বরাদ্দ পাওয়া যায়। ধরে নেওয়া যাক তারা পরের সংলগ্ন ঠিকানাগুলিতে মেমরির সাথে সাথেই শেষ হয় j। আমরা পূর্বে বরাদ্দ করা ভেরিয়েবলের ঠিকানাগুলি রাখতে পয়েন্টারগুলি সেট করেছি: ip1=&i;("আইপিটির আইপিটির ঠিকানাটি অনুলিপি করুন") এবং ip2=&j। লাইনের মধ্যে যা ঘটে তা হ'ল:

Address     Data           Meaning
0x12345680  12 34 56 78    // The variable ip1(equal to address of i)
0x12345684  12 34 56 7C    // The variable ip2(equal to address of j)

সুতরাং আমরা কি পেয়েছিলাম মাত্র 4 মেমরি সংখ্যা বাইট অংশ আছে। দেখার মতো কোথাও কোনও রহস্যময় বা যাদুকর তীর নেই।

প্রকৃতপক্ষে, কেবল একটি মেমরি ডাম্প দেখে, আমরা 0x12345680 ঠিকানাটি একটি intবা আছে কিনা তা বলতে পারি না int*। পার্থক্যটি হল কীভাবে আমাদের প্রোগ্রামটি এই ঠিকানায় সঞ্চিত সামগ্রীগুলি বেছে নিতে বেছে নেয়। (আমাদের প্রোগ্রামটির কাজটি কেবল এই সংখ্যাগুলির সাথে কী করা উচিত তা কেবল সিপিইউকে জানানো))

তারপরে আমরা ইন্ডিয়ারেশনের আরও একটি স্তর যুক্ত করি int** ipp = &ip1;। আবার আমরা কেবল স্মৃতিশক্তি পেয়েছি:

Address     Data           Meaning
0x12345688  12 34 56 80    // The variable ipp

প্যাটার্নটি পরিচিত বলে মনে হচ্ছে না। তবুও আরও একটি সংখ্যা 4 টি বাইট রয়েছে a

এখন, যদি আমাদের উপরের কাল্পনিক ছোট্ট র‌্যামের একটি মেমরি ডাম্প থাকে তবে আমরা ম্যানুয়ালি পরীক্ষা করতে পারি যে এই পয়েন্টারগুলি কোথায় নির্দেশ করে। ippভেরিয়েবলের ঠিকানায় কী সঞ্চিত তা আমরা উঁকি মারি এবং 0x12345680 সামগ্রীটি পাই। কোনটি অবশ্যই ঠিকানা যেখানে ip1সঞ্চিত আছে। আমরা সেই ঠিকানায় যেতে পারি, সেখানকার বিষয়বস্তুগুলি পরীক্ষা করতে পারি, এবং তার ঠিকানা খুঁজে পেতে iপারি এবং শেষ পর্যন্ত আমরা সেই ঠিকানায় যেতে পারি এবং 5 নম্বরটি খুঁজে পেতে পারি।

সুতরাং আমরা যদি আইপিপি এর বিষয়বস্তু গ্রহণ করি *ipp, আমরা পয়েন্টার ভেরিয়েবলের ঠিকানা পাব ip1। লিখে *ipp=ip2আমরা আইপি 2 কে আইপি 1 এ অনুলিপি করি, এটি সমান ip1=ip2। উভয় ক্ষেত্রে আমরা পেতে হবে

Address     Data           Meaning
0x12345680  12 34 56 7C    // The variable ip1
0x12345684  12 34 56 7C    // The variable ip2

(এই উদাহরণগুলি একটি বড় এন্ডিয়ান সিপিইউর জন্য দেওয়া হয়েছিল)


5
যদিও আমি আপনার বক্তব্য গ্রহণ করি, পয়েন্টারগুলি বিমূর্ত, রহস্যময় সত্তা হিসাবে ভাবার মান রয়েছে। পয়েন্টারগুলির কোনও নির্দিষ্ট প্রয়োগ কেবলমাত্র সংখ্যা, তবে আপনি যে বাস্তবায়ন কৌশলটি স্কেচ করেন তা বাস্তবায়নের প্রয়োজনীয়তা নয় , এটি কেবল একটি সাধারণ কৌশল। পয়েন্টারগুলির সমান আকারের দরকার হবে না, পয়েন্টারগুলির ফ্ল্যাট ভার্চুয়াল মেমরির মডেলগুলিতে ঠিকানা হওয়া উচিত নয়; এগুলি নিছক বাস্তবায়নের বিশদ।
এরিক লিপার্ট

@ এরিকলিপার্ট আমি মনে করি যে কেউ প্রকৃত মেমরি ঠিকানা বা ডেটা ব্লক ব্যবহার না করে এই উদাহরণটিকে আরও বিমূর্ত করতে পারে। যদি এটি এমন কোনও টেবিল ছিল location, value, variableযেখানে অবস্থান 1,2,3,4,5এবং মানটি ছিল এমন কিছু উল্লেখ করা হয়েছিল A,1,B,C,3, তবে পয়েন্টারগুলির সম্পর্কিত ধারণাটি তীর ব্যবহার না করে সহজেই ব্যাখ্যা করা যেতে পারে, যা অন্তর্নিহিত বিভ্রান্তিকর। যেটি প্রয়োগ করা হোক না কেন, কোনও স্থানে একটি মান উপস্থিত থাকে এবং এটি ধাঁধাটির টুকরো যা তীরগুলির সাথে মডেলিংয়ের সময় অচল হয়ে যায়।
মিররফেট

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

@ এরিকলিপার্ট এবং হ্যাঁ, পয়েন্টারগুলির বিভিন্ন অস্পষ্ট বাস্তবায়ন থাকতে পারে, যেখানে পয়েন্টারগুলি অগত্যা ঠিকানার সাথে মিলে না। তবে তীর আঁকানো কীভাবে সেগুলি কীভাবে কাজ করে তা আপনাকে বুঝতে সাহায্য করবে না। এক পর্যায়ে আপনাকে বিমূর্ত চিন্তাভাবনা ছেড়ে हार्डवेयर স্তরে নামতে হবে, অন্যথায় আপনি সি ব্যবহার করবেন না এমন খাঁটি বিমূর্ত উচ্চ স্তরের প্রোগ্রামিংয়ের উদ্দেশ্যে অনেক অনেক বেশি উপযুক্ত, আধুনিক ভাষা রয়েছে।
লন্ডিন

@ লন্ডিন: আমি তীর চিত্রের খুব বড় অনুরাগী নই; ডেটা হিসাবে একটি তীর ধারণার একটি কৌশল একটি। আমি এটি বিমূর্তভাবে চিন্তা করতে পছন্দ করি তবে তীর ছাড়াই। &একটি পরিবর্তনশীল উপর অপারেটর আপনি একটি মুদ্রা যে পরিবর্তনশীল প্রতিনিধিত্ব করে দেয়। *যে মুদ্রা উপর অপারেটর আপনি পরিবর্তনশীল ব্যাক দেয়। কোন তীর প্রয়োজন!
এরিক লিপার্ট

8

অ্যাসাইনমেন্টগুলি লক্ষ্য করুন:

ipp = &ip1;

ফলাফল ippনির্দেশ করে ip1

সুতরাং ippনির্দেশ করার জন্য ip2, আমাদের একইভাবে পরিবর্তন করা উচিত,

ipp = &ip2;

যা আমরা পরিষ্কারভাবে করছি না। পরিবর্তে আমরা নির্দেশিত ঠিকানায় মানটি পরিবর্তন করছি ipp
ফোলিং করে

*ipp = ip2;

আমরা কেবল সঞ্চিত মানটি প্রতিস্থাপন করছি ip1

ipp = &ip1এর অর্থ *ipp = ip1 = &i,
এখন *ipp = ip2 = &j,।
সুতরাং, *ipp = ip2মূলত হিসাবে একই ip1 = ip2


5
ipp = &ip1;

পরবর্তী কোনও অ্যাসাইনমেন্ট এর মান পরিবর্তন করে নি ipp। এটি এখনও এটি নির্দেশ করে ip1

আপনি যা দিয়ে *ipp, অর্থাত্‍, যা ip1করেন তার সাথে যে বিষয়টি ippনির্দেশ করা হয়েছে তা বদলে যায় না ip1


5

আমার প্রশ্ন: দ্বিতীয় ছবিতে, আইপিপি এখনও আইপ 1 তে নির্দেশ দিচ্ছে তবে আইপি 2 নয়?

আপনি সুন্দর ছবি স্থাপন করেছেন, আমি দুর্দান্ত আসকি শিল্প করার চেষ্টা করতে যাচ্ছি:

@ রবার্ট-এস-বার্নসের মতো তার উত্তরে বলেছিলেন: পয়েন্টারগুলি ভুলে যান এবং কোনটি কোন দিকে ইঙ্গিত করে তবে মেমরির ক্ষেত্রে বিবেচনা করুন। মূলত, এর int*অর্থ হল এটিতে একটি ভেরিয়েবলের int**ঠিকানা থাকে এবং একটিতে একটি ভেরিয়েবলের ঠিকানা থাকে। তারপরে আপনি মান বা ঠিকানাগুলি অ্যাক্সেস করতে পয়েন্টারের বীজগণিতটি ব্যবহার করতে পারেন: &fooঅর্থ address of fooএবং *fooঅর্থ value of the address contained in foo

সুতরাং, যেমন পয়েন্টারগুলি মেমরির সাথে সম্পর্কিত হয়, আসলে "স্পষ্ট" তৈরি করার সর্বোত্তম উপায় হ'ল পয়েন্টার বীজগণিত স্মৃতিতে কী করে তা দেখানো।

সুতরাং, এখানে আপনার প্রোগ্রামের স্মৃতি (উদাহরণের উদ্দেশ্যটির জন্য সরলীকৃত):

name:    i   j ip1 ip2 ipp
addr:    0   1   2   3   4
mem : [   |   |   |   |   ]

আপনি যখন আপনার প্রাথমিক কোডটি করেন:

int i = 5, j = 6;
int *ip1 = &i, *ip2 = &j;

আপনার স্মৃতি কেমন দেখাচ্ছে তা এখানে:

name:    i   j ip1 ip2
addr:    0   1   2   3
mem : [  5|  6|  0|  1]

সেখানে আপনি দেখতে পারেন ip1এবং ip2ঠিকানা পায় iএবং jএবং ippএখনও বিদ্যমান নেই। ভুলে যাবেন না যে ঠিকানাগুলি কেবল একটি বিশেষ ধরণের দ্বারা সঞ্চিত পূর্ণসংখ্যা।

তারপরে আপনি ঘোষণা এবং সংজ্ঞায়িত করুন ippযেমন:

int **ipp = &ip1;

সুতরাং এখানে আপনার স্মৃতি:

name:    i   j ip1 ip2 ipp
addr:    0   1   2   3   4
mem : [  5|  6|  0|  1|  2]

এবং তারপরে, আপনি সঞ্চিত ঠিকানার মাধ্যমে চিহ্নিত মানটি পরিবর্তন করছেন ipp, যা এতে সঞ্চিত ঠিকানা ip1:

*ipp = ip2;

প্রোগ্রামটির স্মৃতিটি হ'ল

name:    i   j ip1 ip2 ipp
addr:    0   1   2   3   4
mem : [  5|  6|  1|  1|  2]

বিশেষ দ্রষ্টব্য: যেমন int*একটি বিশেষ ধরনের, আমি সবসময় একই লাইনে একাধিক পয়েন্টার প্রকাশক এড়াতে, হিসাবে আমি মনে করি পছন্দ করা int *x;বা int *x, *y;স্বরলিপি বিভ্রান্তিকর হতে পারে। আমি লিখতে পছন্দ করিint* x; int* y;

আছে HTH


আপনার উদাহরণ সহ প্রাথমিক মানটি হওয়া ip2উচিত 3নয়4
ডিপ্টো

1
ওহ, আমি সবেমাত্র স্মৃতি পরিবর্তন করেছি যাতে এটি ঘোষণার ক্রমের সাথে মেলে। আমার ধারণা আমি ঠিক করেছিলাম যে তা করে?
zmo

5

কারণ আপনি যখন বলেন

*ipp = ip2

আপনি ippনির্দেশ করছেন এমন মেমরির দিক নির্দেশ করতে 'অবজেক্ট পয়েন্ট বাই ' বলছেন ip2

আপনি বলার অপেক্ষা রাখে না করছি না ippবিন্দু থেকে ip2


4

আপনি যদি *পয়েন্টারে ডেরেফারেন্স অপারেটর যুক্ত করেন তবে আপনি পয়েন্টার থেকে পয়েন্ট-টু অবজেক্টে পুনর্নির্দেশ করুন।

উদাহরণ:

int i = 0;
int *p = &i; // <-- N.B. the pointer declaration also uses the `*`
             //     it's not the dereference operator in this context
*p;          // <-- this expression uses the pointed-to object, that is `i`
p;           // <-- this expression uses the pointer object itself, that is `p`

অতএব:

*ipp = ip2; // <-- you change the pointer `ipp` points to, not `ipp` itself
            //     therefore, `ipp` still points to `ip1` afterwards.

3

আপনি যদি ippনির্দেশ ip2করতে চান তবে আপনাকে বলতে হবে ipp = &ip2;। যাইহোক, এটি ip1এখনও নির্দেশ করে ছেড়ে যাবে i



3

প্রতিটি ভেরিয়েবল এর মতো প্রতিনিধিত্ব করুন:

type  : (name, adress, value)

সুতরাং আপনার ভেরিয়েবলগুলি এভাবে উপস্থাপন করা উচিত

int   : ( i ,  &i , 5 ); ( j ,  &j ,  6); ( k ,  &k , 5 )

int*  : (ip1, &ip1, &i); (ip1, &ip1, &j)

int** : (ipp, &ipp, &ip1)

মান ippযেমন &ip1তেমন উদ্দীপনা:

*ipp = ip2;

অ্যাডসে &ip1মানটির মানকে পরিবর্তিত করে ip2যার অর্থ ip1পরিবর্তিত হয়:

(ip1, &ip1, &i) -> (ip1, &ip1, &j)

তবে ippএখনও:

(ipp, &ipp, &ip1)

সুতরাং ippস্থির মান &ip1যার অর্থ এটি এখনও নির্দেশ করে ip1


1

কারণ আপনি পয়েন্টারটি পরিবর্তন করছেন *ipp। এর অর্থ

  1. ipp (পরিবর্তনযোগ্য নাম) ---- ভিতরে যান।
  2. ভিতরে ippঠিকানা ip1
  3. এখন *ippতাই (ভিতরে তথ্যের) ফিরে যেতে ip1

এখন আমরা এ ip1*ipp(অর্থাত ip1) = ip2.
ip2এর ঠিকানা ধারণ j.so ip1(ঞ অর্থাৎ ঠিকানা) বিষয়বস্তু ip2 এর ধারণ দ্বারা প্রতিস্থাপন করা হবে, আমরা পরিবর্তন না হয় ippবিষয়বস্তু। এটাই.


1

*ipp = ip2; ইঙ্গিত দেয়:

ip2দ্বারা নির্দেশিত ভেরিয়েবলকে বরাদ্দ করুন ipp। সুতরাং এটি সমান:

ip1 = ip2;

আপনি যদি ঠিকানাটি ip2সঞ্চয় করতে চান তবে ippকেবল করুন:

ipp = &ip2;

এখন ippপয়েন্ট ip2


0

ippপয়েন্টার টাইপ অবজেক্টের একটি পয়েন্টারের (যেমন পয়েন্ট টু) মান রাখতে পারে । যখন তুমি কর

ipp = &ip2;  

তারপরে এর ippমধ্যে ভেরিয়েবলের ঠিকানা (পয়েন্টার) থাকেip2 যা পয়েন্টার&ip2 টাইপ পয়েন্টার ( ) এর ( ) হয় । এখন ippদ্বিতীয় ছবিতে তীরটি নির্দেশ করবে ip2

উইকি বলেছেন: অপারেটর একটি dereference অপারেটর পয়েন্টার ভেরিয়েবল করে পরিচালিত হয়, এবং একটি ফেরৎ L-মান (পরিবর্তনশীল) পয়েন্টার ঠিকানায় মান সমতুল্য। একে পয়েন্টারকে ডিফারেন্সিং বলা হয়।
*

টাইপ করার জন্য পয়েন্টারের এল-ভ্যালুতে একে অপ্রচালিত অবস্থায় *অপারেটর প্রয়োগ করা । অলঙ্কৃত এল-মানটি টাইপ পয়েন্টারটির হয় , এটি কোনও প্রকারের ডেটার ঠিকানা ধরে রাখতে পারে । বিবৃতি দেওয়ার পরে ippint*ippintint

ipp = &ip1;

ippএর ঠিকানাটি ধারণ করে ip1এবং *ippধরে রাখছে (নির্দেশ করে) i। আপনি *ippএটির একটি উপনাম বলতে পারেন ip1। উভয় **ippএবং *ip1এর জন্য উপনাম i
করেছে

 *ipp = ip2;  

*ippএবং ip2উভয়ই একই অবস্থানের ippদিকে নির্দেশ করে তবে এখনও নির্দেশ করছে ip1

*ipp = ip2;আসলে কী তা হ'ল এটি ip2(এর ঠিকানা j) এর বিষয়বস্তু অনুলিপি করে ip1(যেমন *ippএকটি উপাধি হিসাবে ip1) কার্যকরভাবে ফলস্বরূপ উভয় পয়েন্টার তৈরি করে ip1এবং ip2একই বস্তুকে ( j) নির্দেশ করে ।
সুতরাং, দ্বিতীয় চিত্রটিতে, তীর ip1এবং ip2এর দিকে ইশারা করা হচ্ছে jযখন ippএখনও ip1মানটির পরিবর্তন করতে কোনও পরিবর্তন করা হয়নি বলে নির্দেশ করছেipp

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