পয়েন্টার তুলনা কিভাবে?


88

ধরুন আমার 2 টি পয়েন্টার রয়েছে:

int *a = something;
int *b = something;

আমি যদি তাদের তুলনা করতে চাই এবং দেখতে চাই যে তারা একই জায়গায় নির্দেশ করে কিনা (a == খ) কাজ করে?


6
IIRC পয়েন্টার তুলনা undefined হয়, যতক্ষণ না তারা মধ্যে একই অ্যারে উপাদানের দিকে নির্দেশ
sehe

4
@ হেই, নীচে আপনার উত্তরটি এই পুরানো মন্তব্যটি বাতিল করেছে।
স্পেন্সার

উত্তর:


72

হ্যাঁ, এটি পয়েন্টার সমতার সংজ্ঞা: তারা উভয়ই একই অবস্থানের দিকে নির্দেশ করে (বা পয়েন্টার এলিয়াস হয় )


4
পয়েন্টার হ'ল (সাধারণ ব্যক্তির ভাষায়) মূলত আপনার কম্পিউটারের মেমরি ঠিকানার একটি পূর্ণসংখ্যা মান। এটি পূর্ণসংখ্যার সাথে তুলনা করার মতো।
কেমিন ঝো 23

6
@ কেমিনঝো: এটি বেশিরভাগ বর্তমান কম্পিউটারে সত্য, তবে সাধারণভাবে এটি মিথ্যা। এমনকি পুরানো 1980 পিসি এটি 8086 এ এটি মিথ্যা ছিল
বেসাইল স্টারিনকিভিচ

110

একটি বিট জন্য তথ্য এখানে উল্লেখ থেকে প্রাসঙ্গিক লেখা

সমতা অপারেটর (==,! =)

একই ধরণের অবজেক্টের পয়েন্টারগুলিকে 'স্বজ্ঞাত' প্রত্যাশিত ফলাফলের সাথে সমতার জন্য তুলনা করা যেতে পারে:

সি ++ 11 স্ট্যান্ডার্ডের § 5.10 থেকে :

একই ধরণের পয়েন্টার (পয়েন্টার রূপান্তরের পরে) সাম্যের জন্য তুলনা করা যেতে পারে। একই ধরণের দুটি পয়েন্টার সমান তুলনা করে যদি এবং কেবলমাত্র তারা উভয়ই নাল হয় তবে উভয়ই একই ফাংশনের দিকে নির্দেশ করে বা উভয়ই একই ঠিকানার ( 3.9.2 ) উপস্থাপন করে ।

(সদস্যের সাথে পয়েন্টার এবং এবং নাল পয়েন্টার ধ্রুবকের তুলনায় বিশদগুলি রেখে - তারা 'আমি কী বলতে চাইছি' এর একই লাইনটি অবিরত রেখেছি :))

  • [...] উভয় অপারেশন যদি নাল হয় তবে তারা সমান তুলনা করে। অন্যথায় যদি শুধুমাত্র একটি নাল হয় তবে তারা অসম তুলনা করে [[...]

সর্বাধিক 'স্পষ্টাত্মক' ক্যাভ্যাটটির সাথে ভার্চুয়ালগুলির সাথে সম্পর্ক রয়েছে এবং এটি প্রত্যাশা করাও যৌক্তিক জিনিস বলে মনে হচ্ছে:

  • [...] যদি হয় ভার্চুয়াল সদস্য ফাংশনের পয়েন্টার হয় তবে ফলাফলটি অনির্ধারিত। অন্যথায় তারা যদি সমান তুলনা করে তবেই এবং যদি তারা একই শ্রেণীর ধরণের অনুমানিক বস্তুর সাথে সম্মানিত হয় তবে একই সর্বাধিক উত্পন্ন বস্তুর (১.৮) বা একই সাবোবজেক্টের একই সদস্যকে উল্লেখ করে। [...]

সম্পর্কিত অপারেটর (<,>, <=,> =)

সি ++ 11 স্ট্যান্ডার্ডের § 5.9 থেকে :

একই ধরণের অবজেক্টস বা ফাংশনগুলিতে পয়েন্টারগুলি (পয়েন্টার রূপান্তরের পরে) তুলনা করা যেতে পারে, ফলাফলের সাথে নিম্নলিখিত হিসাবে সংজ্ঞায়িত করা হয়:

  1. দুই পয়েন্টার পি এবং একই বস্তু বা ফাংশন, অথবা একই অ্যারে শেষে গত উভয় বিন্দু এক, এর একই ধরনের বিন্দুর কুই বা উভয় নাল, তারপর হন p<=qএবং p>=qউভয় ফলন সত্য এবং p<qএবং p>qউভয় ফলন মিথ্যা।
  2. দুই পয়েন্টার P এবং বিভিন্ন বস্তুর যে একই ধরনের বিন্দুর কুই যদি বা একই বস্তুর অঙ্গ প্রত্যঙ্গগুলি একই অ্যারের উপাদান না হলে বা বিভিন্ন ফাংশন, অথবা যদি শুধুমাত্র তাদের একজন নাল, ফলাফল হল p<q, p>q, p<=q,এবং p>=q অনির্দিষ্ট হয়
  3. যদি দুটি পয়েন্টার একই অবজেক্টের অ স্থিতিশীল ডেটা সদস্যগুলিতে, বা সাবউবজেক্টগুলি বা এই জাতীয় সদস্যদের অ্যারের উপাদানগুলিতে নির্দেশ করে তবে পুনরায় ঘোষণা করা সদস্যটির পয়েন্টারটি বৃহত্তর সাথে তুলনা করে যদি দুটি সদস্যের অ্যাক্সেস নিয়ন্ত্রণ একই থাকে (ধারা 11) এবং তাদের শ্রেনী ইউনিয়ন না হয় শর্ত।
  4. যদি দুটি পয়েন্টার একই অ্যাক্সেসের অ-স্থিতিশীল ডেটা সদস্যদের বিভিন্ন অ্যাক্সেস কন্ট্রোলের সাথে যুক্ত করে (ধারা 11) ফলাফল অনির্ধারিত।
  5. যদি দুটি পয়েন্টার একই ইউনিয়ন অবজেক্টের অ স্থিতিশীল ডেটা সদস্যগুলিকে নির্দেশ করে তবে তারা সমান (তুলনায় রূপান্তর করার পরে void*, যদি প্রয়োজন হয়) তুলনা করে । যদি দুটি পয়েন্টার একই অ্যারের উপাদানগুলিতে বা অ্যারের শেষের বাইরে একটিতে নির্দেশ করে তবে উচ্চতর সাবস্ক্রিপ্ট সহ বস্তুর পয়েন্টারটি উচ্চতর তুলনা করে।
  6. অন্যান্য পয়েন্টার তুলনাগুলি অনির্ধারিত।

সুতরাং, যদি আপনি:

int arr[3];
int *a = arr;
int *b = a + 1;
assert(a != b); // OK! well defined

ঠিক আছে:

struct X { int x,y; } s;
int *a = &s.x;
int *b = &s.y;
assert(b > a); // OK! well defined

তবে এটি somethingআপনার প্রশ্নের মধ্যে নির্ভর করে :

int g; 
int main()
{
     int h;
     int i;

     int *a = &g;
     int *b = &h; // can't compare a <=> b
     int *c = &i; // can't compare b <=> c, or a <=> c etc.
     // but a==b, b!=c, a!=c etc. are supported just fine
}

বোনাস: স্ট্যান্ডার্ড লাইব্রেরিতে আর কী আছে?

§ 20.8.5 / 8 : "টেমপ্লেটের জন্য greater, less, greater_equal, এবং less_equal, কোনো পয়েন্টার টাইপ জন্য বিশেষায়িত একটি মোট অর্ডার উত্পাদ, এমনকি যদি বিল্ট ইন অপারেটর <, >, <=, >=না।"

সুতরাং, আপনি বিশ্বব্যাপী কোনও বিজোড় অর্ডার করতে পারেন void*যতক্ষণ আপনি ব্যবহার করেন std::less<>এবং বন্ধু হিসাবে না খালি না operator<


Would int *a = arr;একটি রেফারেন্স অন্তর্ভুক্ত করা থেকে লাইন সুবিধা stackoverflow.com/questions/8412694/address-of-array ? আমি নই নিশ্চিত হলে প্রশ্ন প্রাসঙ্গিক যথেষ্ট যদিও জিজ্ঞাসা ...
nonsensickle

আজ, অযৌক্তিক @ জেরি কফিন আমাকে এই বিষয়টি সম্পর্কে সচেতন করেছেন যে স্ট্যান্ডার্ড লাইব্রেরিতে ফাংশন অবজেক্ট টেম্পলেটগুলির জন্য সংজ্ঞায়িত করার জন্য আরও কঠোর স্পেসিফিকেশন রয়েছে <functional>। যুক্ত হয়েছে।
sehe

দেখে মনে হচ্ছে চলমান সি ++ খসড়াটিতে এই অধ্যায়টি পরিবর্তিত হয়েছে। আমি এটির ভুল বুঝে না নিলে
সোমউইটউইউজারনেম


25

==পয়েন্টার উপর অপারেটর তাদের সাংখ্যিক ঠিকানা তুলনা করবে এবং অত: পর তা নির্ধারণ যদি তারা একই বস্তুর দিকে নির্দেশ।


12
একাধিক উত্তরাধিকার জড়িত থাকলে এটি আরও জটিল।
ফ্রেডওভারফ্লো 21'14

17

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

যদি আমাদের থাকে

int *a = something; 
int *b = something;

আমরা একই ধরণের দুটি পয়েন্টার যা করতে পারি:

মেমরি ঠিকানা তুলনা করুন:

a==b

এবং সামগ্রীগুলি তুলনা করুন:

*a==*b

1

পয়েন্টার এলিয়াসিং চেক করার জন্য সহজ কোড:

int main () {
    int a = 10, b = 20;
    int *p1, *p2, *p3, *p4;

    p1 = &a;
    p2 = &a;
    if(p1 == p2){
        std::cout<<"p1 and p2 alias each other"<<std::endl;
    }
    else{
        std::cout<<"p1 and p2 do not alias each other"<<std::endl;
    }
    //------------------------
    p3 = &a;
    p4 = &b;
    if(p3 == p4){
        std::cout<<"p3 and p4 alias each other"<<std::endl;
    }
    else{
        std::cout<<"p3 and p4 do not alias each other"<<std::endl;
    }
    return 0;
}

আউটপুট:

p1 and p2 alias each other
p3 and p4 do not alias each other

1

পয়েন্টারগুলির তুলনা পোর্টেবল নয়, উদাহরণস্বরূপ ডস-এ বিভিন্ন পয়েন্টার মান একই স্থানে পয়েন্টার করে, পয়েন্টারগুলির তুলনা মিথ্যা বলে প্রত্যাবর্তন করে।

/*--{++:main.c}--------------------------------------------------*/
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
  int   val_a = 123;
  int * ptr_0 = &val_a;
  int * ptr_1 = MK_FP(FP_SEG(&val_a) + 1, FP_OFF(&val_a) - 16);

  printf(" val_a = %d -> @%p\n", val_a, (void *)(&val_a));
  printf("*ptr_0 = %d -> @%p\n", *ptr_0, (void *)ptr_0);
  printf("*ptr_1 = %d -> @%p\n", *ptr_1, (void *)ptr_1);

  /* Check what returns the pointers comparison: */
  printf("&val_a == ptr_0 ====> %d\n", &val_a == ptr_0);
  printf("&val_a == ptr_1 ====> %d\n", &val_a == ptr_1);
  printf(" ptr_0 == ptr_1 ====> %d\n",  ptr_0 == ptr_1);

  printf("val_a = %d\n", val_a);

  printf(">> *ptr_0 += 100;\n");
             *ptr_0 += 100;

  printf("val_a = %d\n", val_a);

  printf(">> *ptr_1 += 500;\n");
             *ptr_1 += 500;

  printf("val_a = %d\n", val_a);

  return EXIT_SUCCESS;
}
/*--{--:main.c}--------------------------------------------------*/

এটি বোরল্যান্ড সি 5.0 এর অধীনে সংকলন করুন, এখানে ফলাফল:

/*--{++:result}--------------------------------------------------*/
 val_a = 123 -> @167A:0FFE
*ptr_0 = 123 -> @167A:0FFE
*ptr_1 = 123 -> @167B:0FEE
&val_a == ptr_0 ====> 1
&val_a == ptr_1 ====> 0
 ptr_0 == ptr_1 ====> 0
val_a = 123
>> *ptr_0 += 100;
val_a = 223
>> *ptr_1 += 500;
val_a = 723
/*--{--:result}--------------------------------------------------*/
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.