Namespaces
Variants

Comparison operators

From cppreference.net

Операторы сравнения - это бинарные операторы, которые проверяют условие и возвращают 1 , если это условие логически true , и 0 , если это условие false .

Оператор Название оператора Пример Описание
== равно a == b a равно b
! = не равно a ! = b a не равно b
< меньше a < b a меньше b
> больше a > b a больше b
<= меньше или равно a <= b a меньше или равно b
>= больше или равно a >= b a больше или равно b

Содержание

Операторы отношения

Выражения операторов отношения имеют вид

lhs < rhs (1)
lhs > rhs (2)
lhs <= rhs (3)
lhs >= rhs (4)
**Примечание:** В данном HTML-коде нет текста для перевода, так как: - Все элементы содержат только технические термины C++ (`lhs`, `rhs`) - Операторы сравнения (`<`, `>`, `<=`, `>=`) являются частью кода - Номера версий (1)-(4) не требуют перевода - Весь контент находится внутри тегов ` ` или является техническими идентификаторами Структура таблицы и форматирование полностью сохранены.
1) выражение less-than
2) выражение больше
3) выражение меньше или равно
4) выражение "больше или равно"

где

lhs , rhs - выражения, которые оба имеют вещественный тип или оба имеют тип указателя на объект

Тип любого выражения оператора отношения - int , и его значение (которое не является lvalue) равно 1 , когда указанное отношение истинно, и 0 , когда указанное отношение ложно.

Если lhs и rhs являются выражениями любого вещественного типа , тогда

  • usual arithmetic conversions выполняются
  • значения операндов после преобразования сравниваются в обычном математическом смысле (за исключением того, что положительные и отрицательные нули считаются равными, а любое сравнение с участием значения NaN возвращает ноль)

Обратите внимание, что комплексные и мнимые числа нельзя сравнивать с помощью этих операторов.

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

  • указатель на объект, не являющийся элементом массива, рассматривается так, как если бы он указывал на элемент массива с одним элементом
  • если два указателя указывают на один и тот же объект или оба указывают за конец одного и того же массива, они сравниваются как равные
  • если два указателя указывают на разные элементы одного и того же массива, тот, который указывает на элемент с большим индексом, сравнивается как больший
  • если один указатель указывает на элемент массива, а другой указатель указывает за конец того же массива, указатель за концом массива сравнивается как больший
  • если два указателя указывают на члены одной и той же структуры , указатель на член, объявленный позже в определении структуры, сравнивается как больший, чем указатель на член, объявленный ранее
  • указатели на члены одного и того же объединения сравниваются как равные
  • все остальные сравнения указателей вызывают неопределённое поведение
#include <assert.h>
int main(void)
{
    assert(1 < 2);
    assert(2+2 <= 4.0); // int преобразуется в double, два значения 4.0 сравниваются как равные
    struct { int x,y; } s;
    assert(&s.x < &s.y); // члены структуры сравниваются в порядке объявления
    double d = 0.0/0.0; // NaN
    assert( !(d < d) );
    assert( !(d > d) );
    assert( !(d <= d) );
    assert( !(d >= d) );
    assert( !(d == d) );
    float f = 0.1; // f = 0.100000001490116119384765625
    double g = 0.1; // g = 0.1000000000000000055511151231257827021181583404541015625
    assert(f > g); // разные значения
}

Операторы равенства

Выражения оператора равенства имеют вид

lhs == rhs (1)
lhs != rhs (2)
**Примечание:** В данном HTML-коде отсутствует текст для перевода, требующий локализации на русский язык. Все элементы содержат либо HTML-теги и атрибуты, либо C++-специфичные термины (`lhs`, `rhs`, `==`, `!=`), которые согласно инструкциям не подлежат переводу. Числовые обозначения `(1)` и `(2)` также сохраняются в оригинальном виде.
1) выражение equal-to
2) не равно выражению

где

lhs , rhs - выражения, которые
  • оба имеют тип nullptr_t
  • один имеет тип nullptr_t а другой является константой нулевого указателя
(начиная с C23)
  • оба являются указателями на объекты или функции совместимых типов, игнорируя квалификаторы указываемых типов
  • один является указателем на объект, а другой - указателем на (возможно квалифицированный) void
  • один является указателем на объект или функцию, а другой является константой нулевого указателя, такой как NULL или nullptr (начиная с C23)

Тип любого выражения оператора равенства — int , а его значение (не являющееся lvalue) равно 1 , когда указанное отношение выполняется, и 0 , когда указанное отношение не выполняется.

  • если оба операнда имеют арифметические типы, обычные арифметические преобразования выполняются, и полученные значения сравниваются в обычном математическом смысле (за исключением того, что положительные и отрицательные нули считаются равными, а любое сравнение с участием значения NaN, включая равенство с самим собой, возвращает ноль). В частности, значения комплексного типа равны, если их действительные части равны и их мнимые части равны.
  • два значения nullptr_t или одно значение nullptr_t и константа нулевого указателя сравниваются как равные
(начиная с C23)
  • если один операнд является указателем, а другой — константой нулевого указателя, константа нулевого указателя сначала преобразуется в тип указателя (что дает значение нулевого указателя), и два указателя сравниваются, как описано ниже
  • если один операнд является указателем, а другой — указателем на void, не-void указатель преобразуется в указатель на void, и два указателя сравниваются, как описано ниже
  • два указателя сравниваются как равные, если выполняется любое из следующих условий:
  • они оба являются нулевыми указателями своего типа
  • они оба указывают на один и тот же объект или функцию
  • один указатель указывает на объект структуры/объединения/массива, а другой - на его первый член/любой член/первый элемент
  • они оба указывают на позицию за последним элементом одного и того же массива
  • один указывает на позицию за последним элементом массива, а другой - на начало другого массива (того же типа), который следует за первым в более крупном массиве или в структуре без заполнения

(как и с реляционными операторами, указатели на объекты, не являющиеся элементами какого-либо массива, ведут себя как указатели на элементы массивов размера 1)

Примечания

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

Поскольку сравнение указателей работает с указателями на void, макрос NULL может быть определён как ( void * ) 0 в C, хотя это было бы некорректно в C++, где void-указатели не преобразуются неявно в типизированные указатели

При сравнении значений с плавающей запятой на равенство необходимо соблюдать осторожность, поскольку результаты многих операций не могут быть представлены точно и должны округляться. На практике числа с плавающей запятой обычно сравнивают с допуском на разницу в одну или несколько единиц младшего разряда.

#include <assert.h>
int main(void)
{
    assert(2+2 == 4.0); // int преобразуется в double, два значения 4.0 сравниваются как равные
    int n[2][3] = {1,2,3,4,5,6};
    int* p1 = &n[0][2]; // последний элемент в первой строке
    int* p2 = &n[1][0]; // начало второй строки
    assert(p1+1 == p2); // сравниваются как равные
    double d = 0.0/0.0; // NaN
    assert( d != d ); // NaN не равен самому себе
    float f = 0.1; // f = 0.100000001490116119384765625
    double g = 0.1; // g = 0.1000000000000000055511151231257827021181583404541015625
    assert(f != g); // разные значения
}

Ссылки

  • Стандарт C17 (ISO/IEC 9899:2018):
  • 6.5.8 Операторы отношений (стр. 68-69)
  • 6.5.9 Операторы равенства (стр. 69-70)
  • Стандарт C11 (ISO/IEC 9899:2011):
  • 6.5.8 Операторы отношений (стр. 95-96)
  • 6.5.9 Операторы равенства (стр. 96-97)
  • Стандарт C99 (ISO/IEC 9899:1999):
  • 6.5.8 Операторы отношений (стр. 85-86)
  • 6.5.9 Операторы равенства (стр. 86-87)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
  • 3.3.8 Операторы отношения
  • 3.3.9 Операторы равенства

Смотрите также

Приоритет операторов

Общие операторы
присваивание инкремент
декремент
арифметические логические сравнения доступа к членам
доступа
прочие

a = b
a + = b
a - = b
a * = b
a / = b
a % = b
a & = b
a | = b
a ^ = b
a <<= b
a >>= b

++ a
-- a
a ++
a --

+ a
- a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

! a
a && b
a || b

a == b
a ! = b
a < b
a > b
a <= b
a >= b

a [ b ]
* a
& a
a - > b
a. b

a ( ... )
a, b
( type ) a
a ? b : c
sizeof


_Alignof
(начиная с C11)
(до C23)

alignof
(начиная с C23)

C++ документация для Операторов сравнения