পয়েন্টার এক্সপ্রেশন: * পিটিআর ++, * ++ পিটিআর এবং ++ * পিটিআর


128

সম্প্রতি আমি এই সমস্যার মুখোমুখি হয়েছি যা আমি নিজে বুঝতে পারি না।

এই তিনটি এক্সপ্রেশনটির প্রকৃত অর্থ কী?

*ptr++
*++ptr
++*ptr

আমি রিচি চেষ্টা করেছি। কিন্তু দুর্ভাগ্যক্রমে তিনি এই 3 টি অপারেশন সম্পর্কে যা বলেছিলেন তা অনুসরণ করতে অক্ষম হয়েছিল।

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

int main()
{
    const char *p = "Hello";
    while(*p++)
         printf("%c",*p);
    return 0;
}

আমাকে এই আউটপুট দেয়:

ello

তবে আমার প্রত্যাশা ছিল এটি মুদ্রণ করবে Hello। একটি চূড়ান্ত অনুরোধ - দয়া করে আমাকে প্রদত্ত কোড স্নিপেটে প্রতিটি অভিব্যক্তি কীভাবে কাজ করে তার জন্য উদাহরণ দিন। বেশিরভাগ সময় কেবলমাত্র তত্ত্বের অনুচ্ছেদে আমার মাথার উপরে উঠে যায়।


6
আপনি চতুর্থটি মিস করেছেন: (*ptr)++(বন্ধনীগুলি থেকে পৃথক করা দরকার *ptr++)
ব্যবহারকারী 481516234242

15
কারণ আপনি এটি মুদ্রণের আগে পয়েন্টারটি বাড়িয়েছিলেন। আপনি যখন চেয়েছিলেন (* পি) এবং প্রিন্টফ ("% সি", * পি ++);
dcaswell

সাক্ষাত্কারের জন্য দুর্দান্ত প্রশ্ন। সীমাবদ্ধ ব্যবহারিক ব্যবহার। আমি চাই সি এর এই পয়েন্টার না থাকলে :)
হিমাংশু

5
@ হিমাংশু যদি এটি আপনার ইন্টারভিউয়ের নুডল বেক করেন তবে এটি চেষ্টা করুন: একটি বৈশ্বিক পয়েন্টার রাখুন, char* pএকটি অনন্য অক্ষরের বৈধ সমাপ্তিযুক্ত স্ট্রিংকে নির্দেশ করে। তারপর একটি ফাংশন আছে fn(char ch)যে কপি করে প্রিন্ট উভয়ch প্যারামিটার এবং বর্তমান গৃহস্থালির কাজ দ্বারা প্রতি ইঙ্গিত p। এখন জিজ্ঞাসা করুন fn(*p++);প্রশ্ন: fnএকই অক্ষরটি দু'বার মুদ্রণ করে ? আপনি কতজন অধ্যাপকরা এই প্রশ্নটি ভুল পেয়ে অবাক হবেন ?
WhozCraig

1
যেহেতু পি স্ট্রিংকে আক্ষরিক দিকে নির্দেশ করে আপনার লিখতে হবেconst char* p = "Hello";
hetepepphaan

উত্তর:


275

এখানে একটি বিশদ ব্যাখ্যা যা আমি আশা করি সহায়ক হবে। আসুন আপনার প্রোগ্রামটি দিয়ে শুরু করুন, কারণ এটি ব্যাখ্যা করা সবচেয়ে সহজ।

int main()
{
    const char *p = "Hello";
    while(*p++)
        printf("%c",*p);
    return 0;
}

প্রথম বিবৃতি:

const char* p = "Hello";

pএকটি পয়েন্টার হিসাবে ঘোষণা char। যখন আমরা "পয়েন্টার টু এ" বলি char, তার অর্থ কী? এর অর্থ হল এর মান pএকটি এর ঠিকানা char; pস্মৃতিতে একটি রাখার জন্য কিছু স্থান রেখে দেওয়া হয়েছে তা আমাদের জানায় char

বিবৃতিটি pআক্ষরিক স্ট্রিংয়ের প্রথম অক্ষরের দিকে ইঙ্গিত করার জন্যও সূচনা করে "Hello"। এই অনুশীলনের খাতিরে, এটি pপুরো স্ট্রিংকে নয়, কেবল প্রথম চরিত্রের দিকে নির্দেশ করে হিসাবে বোঝা গুরুত্বপূর্ণ 'H'। সর্বোপরি, pএকটিতে একটি পয়েন্টার char, পুরো স্ট্রিংয়ের জন্য নয়। এর মান pএর ঠিকানা হল 'H'মধ্যে "Hello"

তারপরে আপনি একটি লুপ সেট আপ করুন:

while (*p++)

লুপ শর্তটির *p++অর্থ কী? তিনটি জিনিস এখানে কাজ করছে যা এই চমকপ্রদ করে তোলে (কমপক্ষে পরিচিতি স্থাপন না হওয়া পর্যন্ত):

  1. দুটি অপারেটরের অগ্রাধিকার, পোস্টফিক্স ++এবং ইন্ডিরিয়েশন*
  2. পোস্টফিক্স ইনক্রিমেন্ট এক্সপ্রেশনের মান
  3. পোস্টফিক্স ইনক্রিমেন্ট এক্সপ্রেশন এর পার্শ্ব প্রতিক্রিয়া

1. অগ্রাধিকার । অপারেটরদের জন্য অগ্রাধিকার টেবিলের এক দ্রুত নজরে আপনাকে জানাতে হবে যে পোস্টফিক্স ইনক্রিমেন্টের অধিবেশন / ইন্ডিরিশন (15) এর চেয়ে উচ্চতর অগ্রাধিকার (16) রয়েছে। এর অর্থ এই যে জটিল অভিব্যক্তি *p++যাচ্ছে যেমন দলবদ্ধ হবে: *(p++)। অর্থাত্ *অংশটি মানটির ক্ষেত্রে প্রয়োগ করা হবে p++। সুতরাং p++প্রথমে অংশ নেওয়া যাক ।

2. পোস্টফিক্স এক্সপ্রেশন মান । এর মান p++হ'ল p বর্ধনের পূর্বে মান । যদি তোমার থাকে:

int i = 7;
printf ("%d\n", i++);
printf ("%d\n", i);

আউটপুট হবে:

7
8

কারণ বর্ধিত হওয়ার আগে i++মূল্যায়ন করে i। একইভাবে p++বর্তমান মান মূল্যায়ন করতে চলেছে p। যেমনটি আমরা জানি, এর বর্তমান মান pহল ঠিকানা 'H'

সুতরাং এখন p++অংশটি *p++মূল্যায়ন করা হয়েছে; এটির বর্তমান মান p। তারপরে *অংশটি ঘটে। *(current value of p)অর্থ: দ্বারা রাখা ঠিকানায় মান অ্যাক্সেস করুন p। আমরা জানি যে ঠিকানার মানটি 'H'। সুতরাং এক্সপ্রেশন *p++মূল্যায়ন 'H'

এখন বলুন এক মিনিট, আপনি বলছেন। যদি *p++মূল্যায়ন করা হয় 'H', তবে কেন 'H'উপরের কোডটিতে এটি মুদ্রণ হয় না ? পার্শ্ব প্রতিক্রিয়া আসে যেখানে সেখানে ।

৩. পোস্টফিক্স এক্সপ্রেশন এর পার্শ্ব প্রতিক্রিয়া । পোস্টসাফিক্স ++হয়েছে মান বর্তমান প্রতীক, কিন্তু এটা আছে পার্শ্ব প্রতিক্রিয়া যে প্রতীক বৃদ্ধিশীল করুন। তাই না? intআবার সেই কোডটি একবার দেখুন:

int i = 7;
printf ("%d\n", i++);
printf ("%d\n", i);

পূর্বে উল্লিখিত হিসাবে, আউটপুট হবে:

7
8

যখন i++প্রথম মূল্যায়ন করা হয় printf(), এটা 7. মূল্যায়ণ কিন্তু সি মান গ্যারান্টী যে কিছু সময়ে সামনে দ্বিতীয় printf()নির্বাহ শুরু, পার্শ্ব প্রতিক্রিয়া এর ++অপারেটর সঞ্চালিত হবে। অর্থাৎ দ্বিতীয়টি হওয়ার আগে printf(), প্রথমটিতে অপারেটরের iফলস্বরূপ বৃদ্ধি করা হবে । এটি, যাইহোক, মানটি কয়েকটি গ্যারান্টিগুলির মধ্যে অন্যতম যা পার্শ্ব প্রতিক্রিয়াগুলির সময় সম্পর্কে জানায়।++printf()

আপনার কোডে, তারপরে, যখন অভিব্যক্তিটি *p++মূল্যায়ন করা হয়, তখন এটি মূল্যায়ন করে 'H'। তবে আপনি এই সময় পাবেন:

printf ("%c", *p)

যে বিরক্তিকর পার্শ্ব প্রতিক্রিয়া ঘটেছে। pবৃদ্ধি করা হয়েছে। ওহো! এটি আর নির্দেশ করে না 'H', তবে একটি চরিত্রের অতীতকে 'H': 'e'অন্য কথায়। এটি আপনার ককনিফাইড আউটপুট ব্যাখ্যা করে:

ello

সুতরাং অন্যান্য উত্তরে সহায়ক (এবং নির্ভুল) পরামর্শের কোরাস: প্রাপ্ত উচ্চারণ মুদ্রণ করতে "Hello"এবং এর ককনি অংশ নয়, আপনার মতো কিছু দরকার

while (*p)
    printf ("%c", *p++);

এত কিছুর জন্য। বাকিদের কী হবে? আপনি এর অর্থ সম্পর্কে জিজ্ঞাসা করুন:

*ptr++
*++ptr
++*ptr

আমরা প্রায় প্রথম কথা বলত তাই SECOND এ লুক যাক: *++ptr

আমরা আমাদের পূর্বের ব্যাখ্যায় দেখেছি যে পোস্টফিক্স ইনক্রিমেন্টের p++একটি নির্দিষ্ট নজির , একটি মান এবং একটি পার্শ্ব প্রতিক্রিয়া রয়েছে । প্রিফিক্স ইনক্রিমেন্টটি তার পোস্টফিক্স কাউন্টারটির মতো ++pএকই পার্শ্ব প্রতিক্রিয়াযুক্ত : এটি তার ক্রিয়াকলাপকে ১ দ্বারা বাড়িয়েছে However তবে এটির একটি পৃথক নজির এবং ভিন্ন মান রয়েছে

প্রিফিক্স ইনক্রিমেন্টের পোস্টফিক্সের চেয়ে কম অগ্রাধিকার রয়েছে; এটির প্রাধান্য 15 আছে other অন্য কথায়, এটি ডিগ্রিফারেন্স / ইন্ডিरेশন অপারেটরের মতো একই প্রাধান্য রয়েছে *। মত একটি অভিব্যক্তি

*++ptr

কোন বিষয়টি প্রাধান্য নয়: দুটি অপারেটর অগ্রাধিকারের ক্ষেত্রে অভিন্ন। সুতরাং associativity কিক হবে। উপসর্গ বৃদ্ধি এবং অপ্রত্যক্ষ্যতার অপারেটর ডান-বাম associativity আছে। সেই সাহসীতার কারণে অপারেটরটি আরও বামে ptrঅপারেটরের ++আগে ডানদিকের অপারেটরের সাথে গোষ্ঠীবদ্ধ হতে চলেছে *। অন্য কথায়, অভিব্যক্তিটি গ্রুপবদ্ধ হতে চলেছে *(++ptr)। সুতরাং, পাশাপাশি হিসাবে *ptr++অন্য কারণের জন্য, এখানেও *অংশটি মানটির জন্য প্রয়োগ করা হচ্ছে ++ptr

সুতরাং যে মান কি? প্রিফিক্স ইনক্রিমেন্ট এক্সপ্রেশনটির মান হ'ল ইনক্রিমেন্টের পরে অপারেন্ডের মান । এটি পোস্টফিক্স ইনক্রিমেন্ট অপারেটর থেকে একেবারে আলাদা জন্তুতে পরিণত করে। আসুন বলি আপনার কাছে রয়েছে:

int i = 7;
printf ("%d\n", ++i);
printf ("%d\n", i);

আউটপুটটি হবে:

8
8

... আমরা পোস্টফিক্স অপারেটরের সাথে যা দেখেছি তার থেকে আলাদা। একইভাবে, যদি আপনি:

const char* p = "Hello";
printf ("%c ", *p);    // note space in format string
printf ("%c ", *++p);  // value of ++p is p after the increment
printf ("%c ", *p++);  // value of p++ is p before the increment
printf ("%c ", *p);    // value of p has been incremented as a side effect of p++

আউটপুট হবে:

H e e l                // good dog

দেখেন কেন?

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

সুতরাং আমাদের যদি থাকে:

char q[] = "Hello";
char* p = q;
printf ("%c", ++*p);

আশ্চর্যজনকভাবে অহঙ্কারমূলক আউটপুট হতে চলেছে:

I

কি?! ঠিক আছে, সুতরাং *pঅংশটি মূল্যায়ন করতে চলেছে 'H'। তারপরে ++খেলাটি আসে, কোন সময়ে এটি প্রয়োগ করা হবে, বিন্দুটি 'H'মোটেই নয়! আপনি 1 এ যুক্ত করলে কী হয় 'H'? আপনি 1 এর সাথে 'H'72 এর ASCII মান পান ; আপনি 73. উপস্থাপন করে একটি হিসাবে পেতে char, এবং আপনি পেতে char73 এর ASCII মান সঙ্গে 'I'

এটি আপনার প্রশ্নে আপনি যে তিনটি অভিব্যক্তি সম্পর্কে জিজ্ঞাসা করেছিলেন সেটির যত্ন নেয়। আপনার প্রশ্নের প্রথম মন্তব্যে উল্লিখিত আরেকটি এখানে রয়েছে:

(*ptr)++ 

এটি একটি আকর্ষণীয়। যদি তোমার থাকে:

char q[] = "Hello";
char* p = q;
printf ("%c", (*p)++);
printf ("%c\n", *p);

এটি আপনাকে এই উত্সাহী আউটপুট দেবে:

HI

কি হচ্ছে? আবার এটি প্রাধান্য , অভিব্যক্তি মান এবং পার্শ্ব প্রতিক্রিয়াগুলির বিষয় । বন্ধনীগুলির কারণে, *pঅংশটি প্রাথমিক অভিব্যক্তি হিসাবে বিবেচিত হয়। প্রাথমিক এক্সপ্রেশন অন্য সব কিছু ট্রাম্প; তারা প্রথমে মূল্যায়ন করা। এবং *p, আপনি জানেন হিসাবে, মূল্যায়ন 'H'। বাকী বাক্য ++অংশটি সেই মানটিতে প্রয়োগ করা হয়। সুতরাং, এই ক্ষেত্রে, (*p)++হয়ে যায় 'H'++

এর মান কী 'H'++? আপনি যদি বলেন 'I', আপনি পোস্টফিক্স ইনক্রিমেন্টের সাথে মান বনাম পার্শ্ব প্রতিক্রিয়া সম্পর্কে আমাদের আলোচনাটি ইতিমধ্যে ভুলে গেছেন (ইতিমধ্যে!) মনে রাখবেন, 'H'++এর বর্তমান মানটির মূল্যায়ন করে 'H'। সুতরাং যে প্রথম printf()মুদ্রণ যাচ্ছে 'H'। তারপরে, পার্শ্ব প্রতিক্রিয়া হিসাবে , এতে 'H'বাড়ানো হচ্ছে 'I'। দ্বিতীয় printf()প্রিন্ট যে 'I'। এবং আপনি আপনার প্রফুল্ল শুভেচ্ছা আছে।

ঠিক আছে, তবে শেষ দুটি ক্ষেত্রে আমার কেন দরকার আছে

char q[] = "Hello";
char* p = q;

কেন আমি ঠিক যেমন কিছু করতে পারি না

/*const*/ char* p = "Hello";
printf ("%c", ++*p);   // attempting to change string literal!

কারণ "Hello"একটি স্ট্রিং আক্ষরিক। যদি আপনি চেষ্টা করেন তবে আপনি স্ট্রিংটিতে পুরো স্ট্রিংটি তৈরি করে ++*pপাল্টানোর চেষ্টা করছেন । সি তে, স্ট্রিং লিটারেলগুলি কেবল পঠনযোগ্য; তাদের সংশোধন করার চেষ্টা অনির্ধারিত আচরণের জন্য প্রার্থনা করে। ইংরেজিতেও অপরিজ্ঞাত, তবে এটি কেবল কাকতালীয়।'H''I'"Iello""Iello"

বিপরীতে, আপনি থাকতে পারে না

char p[] = "Hello";
printf ("%c", *++p);  // attempting to modify value of array identifier!

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

মোট কথা, আপনি যে তিনটি বিষয় সম্পর্কে জিজ্ঞাসা করেছেন তা এখানে:

*ptr++   // effectively dereferences the pointer, then increments the pointer
*++ptr   // effectively increments the pointer, then dereferences the pointer
++*ptr   // effectively dereferences the pointer, then increments dereferenced value

এবং এখানে চতুর্থটি, অন্য তিনটির মতো প্রতিটি মজার পরিমাণ:

(*ptr)++ // effectively forces a dereference, then increments dereferenced value

প্রথম এবং দ্বিতীয়টি ক্র্যাশ হবে যদি ptrআসলে কোনও অ্যারে সনাক্তকারী হয়। তৃতীয় এবং চতুর্থ ক্র্যাশ হয়ে যাবে যদি ptrএকটি স্ট্রিং আক্ষরিককে নির্দেশ করে।

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


22
এই ফোরামে আসার আগে আমি নিজের মালিকানাধীন 3 টি "সি" বই অনুসন্ধান করেছি। আমি কয়েকটি উল্লেখযোগ্য অনলাইন টিউটোরিয়ালও চেষ্টা করেছি। তবে এগুলির কোনওটিই আপনার ব্যাখ্যার কাছে আসে না (বিশেষত যেভাবে আপনি এটি সব একসাথে রেখেছেন)। আমি যে প্রশ্নটি করেছি তার উত্তর আপনিই দেননি, তৃণমূল থেকে আপনি আরও অনেক বিষয় নিয়ে আলোচনা করেছেন। আসলে আপনি আজ আমাকে অনেক মৌলিক বিষয় শিখিয়েছেন, যার আমার আগে অভাব ছিল। আমি আমার গৃহীত উত্তর টগল করে সাহায্য করতে পারি না। :) আবার ধন্যবাদ.
বরাদ্দ করা হয়েছে

26
+1 আমি মনে করি এটি এসওতে পড়েছি এটি একটি দীর্ঘ দীর্ঘ উত্তর। আমি মনে করি এই উত্তর থেকে প্রত্যেকে অনেক কিছু শিখতে পারে।
শফিক ইয়াঘমোর

9
আপনার স্যার, সি তে একটি বই লিখতে হবে
ডিলন বার্টন

1
একটি ভাল প্রশ্নের কি সুন্দর উত্তর! ভাল হয়েছে @verbose!
বেনকা

7
আপনি @verbose স্যার, আপনার নাম পর্যন্ত বসবাস .. :)
sleeping_dragon

44

ধরুন ptrঅ্যারের আই-থিম উপাদানটির দিকে নির্দেশ করুন arr

  1. *ptr++মূল্যায়ন করে arr[i]এবং ptrএর (i + 1) -তম উপাদানটির দিকে নির্দেশ করে arr। এটি সমান *(ptr++)

  2. *++ptrptrএর (i + 1) -th এলিমেন্টের দিকে নির্দেশ করতে সেট করে arrএবং এতে মূল্যায়ন করে arr[i+1]। এটি সমান *(++ptr)

  3. ++*ptrarr[i]এক দ্বারা বৃদ্ধি পায় এবং এর বর্ধিত মানের মূল্যায়ন করে; পয়েন্টারটি ptrঅপরিবর্তিত রয়েছে। এটি সমান ++(*ptr)

আরও একটি রয়েছে, তবে এটি লেখার জন্য আপনার প্রথম বন্ধনী প্রয়োজন:

  1. (*ptr)++arr[i]এক এক দ্বারা বৃদ্ধি পায় এবং বৃদ্ধি হওয়ার আগে এর মানটির মূল্যায়ন করে; পয়েন্টারটি ptrআবার ছোঁয়াচে পড়ে আছে।

বাকি আপনি নিজেরাই বের করতে পারবেন; এটি জাগুয়ার দ্বারা উত্তরও দেওয়া হয়েছিল।


13

*ptr++ : post increment a pointer ptr

*++ptr : Pre Increment a pointer ptr

++*ptr : preincrement the value at ptr location

প্রাক ইনক্রিমেন্ট এবং পোস্ট ইনক্রিমেন্ট অপারেটরদের সম্পর্কে এখানে পড়ুন


এটি Helloআউটপুট হিসাবে দেবে

int main()
{
    const char *p = "Hello";
    while(*p)
         printf("%c",*p++);//Increment the pointer here 
    return 0;
}

@ Nik-Lz হ্যাঁ, আউটপুট হবেHello
Jainendra

7

আপনার লুপের অবস্থা খারাপ:

while(*p++)
    printf("%c",*p);

হিসাবে একই

while(*p)
{
    p++;
    printf("%c",*p);
}

এবং এটি ভুল, এটি হওয়া উচিত:

while(*p)
{
    printf("%c",*p);
    p++;
} 

*ptr++যেমনটি *(ptr++)হ'ল:

const char  *ptr = "example";
char  value;

value = *ptr;
++ptr;
printf("%c", value); // will print 'e'

*++ptrযেমনটি *(++ptr)হ'ল:

const char  *ptr = "example";
char  value;

++ptr;
value = *ptr;
printf("%c", value); // will print 'x'

++*ptrযেমনটি ++(*ptr)হ'ল:

const char  *ptr = "example";
char  value;

value = *ptr;
++value;
printf("%c", value); // will print 'f' ('e' + 1)

আমি উত্তরের প্রথম অংশের সাথে একমত হই। দ্বিতীয় অংশে, পূর্ণসংখ্যার সাথে পয়েন্টার (সংখ্যায়!) আরম্ভ করা এমন কারও জন্য বিভ্রান্তিকর যা পয়েন্টার ব্যবহার বোঝার জন্য সংগ্রাম করছে।
নিকি

4

আপনি অগ্রাধিকার সম্পর্কে ঠিক বলেছেন, নোট করুন যে *উপসর্গের অগ্রগতির চেয়ে অগ্রাধিকার রয়েছে, তবে পোস্টফিক্স ইনক্রিমেন্টের চেয়ে বেশি নয়। এই ভাঙ্গন এখানে কীভাবে:

*ptr++ - বাম থেকে ডান দিকে যাচ্ছেন, পয়েন্টারকে অবজ্ঞা করুন এবং তারপরে পয়েন্টারটির মান বাড়িয়ে তুলুন (অবাস্তবতার চেয়ে পোস্টফিক্সের প্রাধান্যের কারণে এটি কী নির্দেশ করে)

*++ptr - পয়েন্টারটি বৃদ্ধি করুন এবং তারপরে এইটিকে উপেক্ষিত করুন, কারণ উপসর্গ এবং ডেরিফার্সের একই প্রাধান্য রয়েছে এবং তাই ডান থেকে বামে ক্রমে তাদের মূল্যায়ন করা হয়

++*ptr- অগ্রাধিকারের দিক থেকে উপরের মতো, আবার ডান থেকে বামে ক্রমানুসারে পয়েন্টারটিকে অবচয় করে এবং তারপরে পয়েন্টারটি কী নির্দেশ করে। দয়া করে নোট করুন যে এটি আপনার ক্ষেত্রে এটি অপরিজ্ঞাত আচরণের দিকে পরিচালিত করবে কারণ আপনি কেবল পঠনযোগ্য ভেরিয়েবল ( char* p = "Hello";) পরিবর্তন করতে চেষ্টা করছেন ।


3

আমি আমার গ্রহণ যুক্ত করতে যাচ্ছি কারণ অন্য উত্তরগুলি সঠিক হওয়ার পরেও আমি মনে করি তারা কিছু অনুপস্থিত।

 v = *ptr++

মানে

 temp = ptr;
 ptr  = ptr + 1
 v    = *temp;

যেখানে হিসাবে

 v = *++ptr

মানে

 ptr = ptr + 1
 v   = *ptr

পোস্ট বৃদ্ধি (এবং পোস্ট হ্রাস) এর অর্থ বোঝা গুরুত্বপূর্ণ

 temp = ptr       // Temp created here!!!
 ptr  = ptr + 1   // or - 1 if decrement)
 v    = *temp     // Temp destroyed here!!!

কেন এটা কোন ব্যাপার? ভাল ইন সি যে এত গুরুত্বপূর্ণ নয়। সি ++ এ যদিও ptrএটিরর মতো জটিল ধরনের হতে পারে। উদাহরণ স্বরূপ

 for (std::set<int>::iterator it = someSet.begin(); it != someSet.end(); it++)

এই ক্ষেত্রে, কারণ itএকটি জটিল টাইপ it++কারণ সম্ভবত tempসৃষ্টির কারণে পার্শ্ব প্রতিক্রিয়া হতে পারে । অবশ্যই আপনি যদি ভাগ্যবান হন তবে সংকলকটি কোডটি নিক্ষেপ করার চেষ্টা করবে যা প্রয়োজন নেই তবে যদি পুনরুক্তির নির্মাণকারী বা ধ্বংসকারী কিছু করে থাকে তবে it++এটি তৈরি করার সময় সেগুলি প্রভাবগুলি প্রদর্শন করতে চলেছে temp

আমি যা বলতে চাইছি তার সংক্ষিপ্তটি হ'ল রাইট হোয়াট ইউ মানে । আপনি যদি ইনক্রিমেন্ট পিটিআর বলতে চান তবে লিখবেন ++ptrনা ptr++। আপনি যদি বলতে চান temp = ptr, ptr += 1, tempতাহলে লিখুনptr++


0
*ptr++    // 1

এটি একই হিসাবে:

    tmp = *ptr;
    ptr++;

সুতরাং নির্দেশিত বস্তুর মান ptrপুনরুদ্ধার করা হয়, তারপরে ptrবৃদ্ধি করা হয়।

*++ptr    // 2

এটি একই হিসাবে:

    ++ptr;
    tmp = *ptr;

সুতরাং পয়েন্টারটি ptrবাড়ানো হয়, তারপরে নির্দেশিত বস্তুটি ptrপড়ে।

++*ptr    // 3

এটি একই হিসাবে:

    ++(*ptr);

সুতরাং নির্দেশিত বস্তুটি ptrবৃদ্ধি করা হয়; ptrনিজেই অপরিবর্তিত।


0

পোস্টফিক্স এবং উপসর্গের ক্ষেত্রে ডেরেফারেন্সের চেয়ে বেশি অগ্রাধিকার রয়েছে

* পিটিআর ++ এখানে ইনক্রিমেন্ট পিটিআর পোস্ট করুন এবং তারপরে পিটিআরটির নতুন মানের দিকে ইশারা করুন

* ++ পিটিআর এখানে প্রাক বৃদ্ধির প্রথম মুষ্টি তারপর পিটিআর এর নতুন মানের দিকে ইশারা করে

++ * পিটিআর এখানে প্রথমে পিটিআর পয়েন্টিংয়ের মান এবং সেই ভ্যালু বৃদ্ধির মান পান


1
এটি ভুল। পোস্টফিক্সের উচ্চতর প্রাধান্য রয়েছে তবে উপসর্গের ক্ষেত্রে ডিরিফারেন্সের সমান নজির রয়েছে।
ভার্জোজ

0

পয়েন্টার এক্সপ্রেশন: * পিটিআর ++, * ++ পিটিআর এবং ++ * পিটিআর:

দ্রষ্টব্য : পয়েন্টারগুলি অবশ্যই আরম্ভ করা উচিত এবং এর বৈধ ঠিকানা থাকতে হবে। কারণ র‌্যামে আমাদের প্রোগ্রাম (এটআউট) বাদে আরও অনেকগুলি প্রোগ্রাম এক সাথে চলমান রয়েছে যদি আপনি এমন কিছু মেমরি অ্যাক্সেস করার চেষ্টা করেন যা সেগমেন্টেশন ত্রুটির মাধ্যমে ওএসের জন্য সংরক্ষিত ছিল না।

এর ব্যাখ্যা দেওয়ার আগে কি সাধারণ উদাহরণ বিবেচনা করা যায়?

#include<stdio.h>
int main()
{
        int num = 300;
        int *ptr;//uninitialized pointer.. must be initialized
        ptr = &num;
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
        *ptr = *ptr + 1;//*ptr means value/data on the address.. so here value gets incremented
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
        /** observe here that "num" got changed but manually we didn't change, it got modified by pointer **/
        ptr = ptr + 1;//ptr means address.. so here address got incremented
        /**     char pointer gets incremented by 1 bytes
          Integer pointer gets incremented by 4 bytes
         **/
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}

উপরের কোডটির আউটপুট বিশ্লেষণ করুন, আমি আশা করি আপনি উপরের কোডটির আউটপুট পেয়েছেন। উপরের কোড থেকে একটি জিনিস স্পষ্ট যে পয়েন্টার নাম ( পিটিআর ) এর অর্থ আমরা ঠিকানা সম্পর্কে কথা বলছি এবং * পিটিআর মানে আমরা মূল্য সম্পর্কে মূল্যবান / ডেটা কথা বলছি ।

CASE 1 : * ptr ++, * ++ ptr, * (ptr ++) এবং * (++ ptr):

উপরে উল্লিখিত সমস্ত 4 বাক্য গঠন address gets incrementedএকইরূপে, ঠিক কীভাবে ঠিকানাটি আলাদা হয় তা আলাদা।

দ্রষ্টব্য : যে কোনও অভিব্যক্তি সমাধানের জন্য এক্সপ্রেশনটিতে কতজন অপারেটর রয়েছে তা খুঁজে বের করুন, তারপরে অপারেটরের অগ্রাধিকারগুলি সন্ধান করুন । আমি একাধিক একই অগ্রাধিকার থাকার অপারেটার তারপর বিবর্তন বা ক্রম পরীক্ষা associativity যে অধিকার (রাঃ) অবশিষ্ট আছে (এল) এর OT বাম থেকে ডানে পারে।

* পিটিআর ++ : এখানে ২ জন অপারেটর রয়েছেন যথা ডি-রেফারেন্স (*) এবং ++ (ইনক্রিমেন্ট)। উভয়ই একই অগ্রাধিকার পাচ্ছে তারপরে সাহচর্য যা যা আর থেকে এল হয় তা পরীক্ষা করে So সুতরাং ডান থেকে বামদিকে সমাধান শুরু করুন, অপারেটররা যেদিকে প্রথমে আসবে।

* পিটিআর ++ : আর + এল থেকে সমাধান করার সময় প্রথম ++ এসেছে, সুতরাং ঠিকানাটি বর্ধিত হয় তবে তার পোস্টের বৃদ্ধি হয়।

* ++ পিটিআর : এখানে প্রথম হিসাবে একই ঠিকানাও বর্ধিত হয় তবে এর প্রাক বৃদ্ধি ment

* (পিটিআর ++) : এখানে 3 জন অপারেটর রয়েছে তাদের মধ্যে গ্রুপিং () সর্বোচ্চ অগ্রাধিকার পাচ্ছে, সুতরাং প্রথম পিটিআর ++ সলভ করা অর্থাৎ ঠিকানা বর্ধিত তবে পোস্ট হয়।

* (++ পিটিআর) : উপরের ক্ষেত্রে একইভাবে ঠিকানাও বর্ধিত হয় তবে প্রাক বৃদ্ধি হয়।

CASE 2 : ++ * পিটিআর, ++ (* পিটিআর), (* পিটিআর) ++:

উপরে উল্লিখিত সমস্ত 4 বাক্য গঠন একইরূপে, সমস্ত মান / উপাত্তে বৃদ্ধি পায় তবে মান কীভাবে পরিবর্তিত হয় তা ভিন্ন।

++ * পিটিআর : আর * থেকে এল-তে সমাধান করার সময় প্রথম * এসেছে, সুতরাং মান পরিবর্তিত হয় তবে এর পূর্ববৃদ্ধি হয়।

++ (* পিটিআর) : উপরের ক্ষেত্রে একই, মান সংশোধন করা হয়।

(* পিটিআর) ++ : এখানে 3 জন অপারেটর রয়েছে, তাদের মধ্যে গ্রুপিং () সর্বোচ্চ অগ্রাধিকার পাচ্ছে, ইনসাইড () * পিটিআর আছে, সুতরাং প্রথম * পিটিআর সমাধান করা হয় অর্থাৎ মান বৃদ্ধি পায় তবে পোস্ট হয়।

দ্রষ্টব্য : ++ * ptr এবং * ptr = * ptr + 1 উভয়ই একই, উভয় ক্ষেত্রেই মান পরিবর্তন হয়। ++ * পিটিআর: কেবলমাত্র 1 টি নির্দেশ (আইএনসি) ব্যবহৃত হয়, একক শটে সরাসরি মান পরিবর্তিত হয়। * পিটিআর = * পিটিআর + ১: এখানে প্রথমে মান বাড়ানো হয় (আইএনসি) এবং তারপরে নির্ধারিত (এমওভি)।

পয়েন্টারের উপরের সমস্ত বৃদ্ধির বিভিন্ন বাক্য গঠন বোঝার জন্য সহজ কোডটি বিবেচনা করা যাক:

#include<stdio.h>
int main()
{
        int num = 300;
        int *ptr;
        ptr = &num;
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
        *ptr++;//address changed(post increment), value remains un-changed
//      *++ptr;//address changed(post increment), value remains un-changed
//      *(ptr)++;//address changed(post increment), value remains un-changed
//      *(++ptr);//address changed(post increment), value remains un-changed

//      ++*ptr;//value changed(pre increment), address remains un-changed
//      (*ptr)++;//value changed(pre increment), address remains un-changed
//      ++(*ptr);//value changed(post increment), address remains un-changed

        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}

উপরের কোডে মন্তব্য / আন-মন্তব্য মন্তব্য করার চেষ্টা করুন এবং ফলাফলগুলি বিশ্লেষণ করুন।

কনস্ট্যান্ট হিসাবে পয়েন্টার : এমন কোনও উপায় নেই যার মাধ্যমে আপনি পয়েন্টারকে ধ্রুবক হিসাবে তৈরি করতে পারেন, খুব কম আমি এখানে উল্লেখ করছি।

1) const int- * P বা int- এ const * পি : এখানে valueহয় ধ্রুবক , ঠিকানা নয় ধ্রুবক অর্থাত যেখানে পি নির্দেশ করা হয়? কিছু ঠিকানা? সেই ঠিকানায় মান কী? কিছু মান আছে? এই মানটি স্থির, আপনি সেই মানটি সংশোধন করতে পারবেন না তবে পয়েন্টারটি কোথায় নির্দেশ করছে? কিছু ঠিক আছে? এটি অন্য ঠিকানায়ও নির্দেশ করতে পারে।

এটি বুঝতে নীচে কোড বিবেচনা করতে দিন:

#include<stdio.h>
int main()
{
        int num = 300;
        const int *ptr;//constant value, address is modifible
        ptr = &num;
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
        *ptr++;//
//      *++ptr;//possible bcz you are trying to change address which is possible
//      *(ptr)++;//possible
//      *(++ptr);//possible

//      ++*ptr;//not possible bcz you trying to change value which is not allowed
//      (*ptr)++;//not possible
//      ++(*ptr);//not possible

        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}

উপরের কোডটির আউটপুট বিশ্লেষণ করার চেষ্টা করুন

2) ইন্ট কনস্ট * পি : একে বলা হয় ' **constant pointe**r' অর্থাৎ address is constant but value is not constant। এখানে আপনাকে ঠিকানা পরিবর্তন করার অনুমতি নেই তবে আপনি মানটি পরিবর্তন করতে পারবেন।

দ্রষ্টব্য : ধ্রুব পয়েন্টার (উপরের কেস) নিজেই ঘোষণা করার সময় শুরু করতে হবে।

এটি বুঝতে সহজ কোডটি চেক করতে দেয়।

#include<stdio.h>
int main()
{
        int x = 300;
        int* const p;
        p = &x;
        printf("x = %d p =%p and *p = %d\n",num,p,*p);
}

উপরের কোডে, যদি আপনি পর্যবেক্ষণ করেন যে কোনও ++ * পি বা * পি ++ নেই তাই আপনি ভাবতে পারেন এটি সহজ ঘটনা কারণ আমরা ঠিকানা বা মান পরিবর্তন করছি না তবে এটি ত্রুটি সৃষ্টি করবে। কেন? কারণ আমি মন্তব্যে উল্লেখ।

#include<stdio.h>
int main()
{
        int x = 300;
        /** constant pointer must initialize while decaring itself **/
        int* const p;//constant pointer i.e its pointing to some address(here its pointing to garbage), it should point to same address(i.e garbage ad
dress only 
        p = &x;// but here what we are doing ? we are changing address. we are making p to point to address of x instead of garbage address.
        printf("x = %d p =%p and *p = %d\n",num,p,*p);
}

তাহলে এই সমস্যার সমাধান কী?

     int* const p = &x;

এই ক্ষেত্রে সম্পর্কে আরও নীচের উদাহরণ বিবেচনা করা যাক।

#include<stdio.h>
int main()
{
        int num = 300;
        int *const ptr = &num;//constant value, address is modifible
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
        *ptr++;//not possible
//      *++ptr;//not possible bcz you are trying to change address which is not possible
//      *(ptr)++;//not possible
//      *(++ptr);//not possible

//      ++*ptr;// possible bcz you trying to change value which is allowed
//      (*ptr)++;// possible
//      ++(*ptr);// possible
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}

3) কনট ইন্ট * কনস্ট পি : এখানে ঠিকানা এবং মান উভয়ই ধ্রুবক

এটি বুঝতে কোড নীচে চেক করা যাক

#include<stdio.h>
int main()
{
        int num = 300;
        const int* const ptr = &num;//constant value,constant address 
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
        *ptr++;//not possible
        ++*ptr;//not possible
        printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}

-1
const char *p = "Hello";   

*p means "Hello"
          ^
          | 
          p

*p++ means "Hello"
             ^
             | 
             p

*++p means "Hello"
            ^
            |     (WHILE THE STATEMENT IS EXECUTED)
            p

*++p means "Hello"
             ^
             |     (AFTER THE STATEMENT IS EXECUTED)
             p

++*pএর অর্থ হল যে আপনি *pযার ASCII মান বাড়ানোর চেষ্টা করছেন

   is "Hello"
       ^
       | 
       p

আপনি মানটিকে বৃদ্ধি করতে পারবেন না কারণ এটি একটি ধ্রুবক যাতে আপনি একটি ত্রুটি পান

আপনার লুপটি লুপটি *p++স্ট্রিংয়ের শেষ প্রান্তে পৌঁছা পর্যন্ত চলে যেখানে একটি '\0'(NULL) অক্ষর রয়েছে।

যেহেতু *p++প্রথম অক্ষরটি এড়িয়ে যায় আপনি কেবল নিজের অক্ষরটি দ্বিতীয় অক্ষর থেকে শুরু করবেন।

নিম্নলিখিত কোডটি কোনও কিছুই আউটপুট দেয় না কারণ লুপ রয়েছে '\0'

const char *p = "Hello";
    while('\0') 
         printf("%c",*p);

নিম্নলিখিত কোডটি আপনাকে পরের কোড অর্থাৎ ইলো হিসাবে একই আউটপুট দেবে।

const char *p = "Hello";
    while(*++p)
         printf("%c",*p);

...................................

const char *p = "Hello";
    while(*p++)
         printf("%c",*p);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.