Как сравнить указатели?



Предположим, у меня есть 2 указателя:



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


если я хочу сравнить их и посмотреть, указывают ли они на одно и то же место (a == b) работает?

686   5  

5 ответов:

Да, это определение равенства указателей: они оба указывают на одно и то же место (или указатель псевдонимов)

, если факты вот соответствующий текст из спецификации

оператор равенства (==,!=)

указатели на объекты одного типа можно сравнить для равенства с "интуитивными" ожидаемыми результатами:

С § 5.10 стандарта C++11:

указатели одного типа (после преобразования указателя) можно сравнить для равенства. Сравнение двух указателей одного типа равны, если и только если они оба нулевые, оба указывают на одну и ту же функцию, или оба представляют один и тот же адрес (3.9.2).

(оставляя без внимания детали сравнения указателей на член и или константы нулевого указателя-они продолжают вниз по той же строке "делать то, что я имею в виду":)

  • [... Если оба операнда равны null, то они считаются равными. В противном случае, если только один нуль, они считаются равными.[...]

самое "заметное" предостережение связано с виртуалами, и, похоже, это тоже логично ожидать:

  • [...] если любой из них является указателем на виртуальную функцию-член, результат не определен. В противном случае они сравнение равно тогда и только тогда, когда они будут ссылаться на один и тот же член одного и того же самого производного объекта (1.8) или тот же самый подобъект, если они были разыменованы с гипотетическим объектом связанного типа класса. [...]

реляционные операторы (,=)

С § 5.9 стандарта C++11:

указатели на объекты или функции одного типа (после преобразования указателей) можно сравнить, с результатом, определенным следующим образом:

  1. если два указателя p и q одного типа указывают на один и тот же объект или функция, или оба указывают на один конец одного и того же массива, или оба null, тогда p<=q и p>=q оба дают true и p<q и p>q оба дают false.
  2. если два указателя p и q одного типа указывают на разные объекты, которые are не члены одного объекта или элементы одного массива или в разных функции, или если только один из них равен нулю, то результаты 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<.

на == оператор на указателях будет сравнивать их числовой адрес и, следовательно, определять, указывают ли они на один и тот же объект.

подведем итог. Если мы хотим увидеть, указывают ли два указателя на одну и ту же ячейку памяти, мы можем это сделать. Кроме того, если мы хотим сравнить содержимое памяти, на которое указывают два указателя, мы можем сделать это тоже, просто помните, чтобы сначала разыменовать их.

Если у нас есть

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

, которые являются двумя указателями одного типа можно:

сравнить адреса памяти:

a==b

и сравниваем содержание:

*a==*b

допустим, у вас есть указатели:

int *a = something1;
int *b = something2;

вы знаете адрес something1, который является &something1. Также адрес something2 - это &something2.

Итак, что вам нужно сделать, это проверить правильность двух адресов, на которые указывают указатели.

таким образом, вы используете что-то вроде

if(&something1 == &something2) {
//do something
}

или вы можете использовать оператор==, чтобы проверить, имеет ли указатель a равное значение с указателем b.

Comments

    Ничего не найдено.