Spec-Zone.ru › C

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

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

Оператор Название оператора Пример Описание
== равно 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)
1) выражение меньше
2) выражение больше
3) выражение меньше или равно
4) выражение больше или равно

где

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

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

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

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

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

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

  • указатель на объект, который не является элементом массива, обрабатывается так, как будто он указывает на элемент массива с одним элементом
  • если два указателя указывают на один и тот же объект или оба указывают на элемент сразу после конца одного и того же массива, они сравниваются как равные
  • если два указателя указывают на разные элементы одного и того же массива, указатель, указывающий на элемент с большим индексом, сравнивается как больший
  • если один указатель указывает на элемент массива, а другой — на элемент сразу после конца того же массива, указатель, указывающий на элемент сразу после конца, сравнивается как больший
  • если два указателя указывают на члены одного и того же структуры, указатель на член, объявленный позже в определении структуры, сравнивается как больший, чем указатель на член, объявленный ранее
  • указатели на члены одного и того же объединения сравниваются как равные
  • все остальные сравнения указателей вызывают неопределенное поведение
#include <assert.h>
int main(void)
{
    assert(1 < 2);
    assert(2+2 <= 4.0); // int converts to double, two 4.0's compare equal
 
    struct { int x,y; } s;
    assert(&s.x < &s.y); // struct members compare in order of declaration
 
    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); // different values
}

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

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

lhs == rhs (1)
lhs != rhs (2)
1) выражение равно
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, и два указателя сравниваются, как описано ниже
  • два указателя сравниваются как равные, если выполняется любое из следующих условий:
    • они оба являются нулевыми значениями указателей своего типа
    • они оба указывают на один и тот же объект или функцию
    • один указатель указывает на объект типа struct/union/массив, а другой — на его первый член/любой член/первый элемент
    • они оба указывают на элемент сразу после последнего элемента одного и того же массива
    • один указывает на элемент сразу после конца массива, а другой — на начало другого массива (того же типа), который следует за первым в большем массиве или в структуре без заполнения

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

Примечания

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

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

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

#include <assert.h>
int main(void)
{
    assert(2+2 == 4.0); // int converts to double, two 4.0's compare equal
 
    int n[2][3] = {1,2,3,4,5,6};
    int* p1 = &n[0][2]; // last element in the first row
    int* p2 = &n[1][0]; // start of second row
    assert(p1+1 == p2); // compare equal
 
    double d = 0.0/0.0; // NaN
    assert( d != d ); // NaN does not equal itself
 
    float f = 0.1; // f = 0.100000001490116119384765625
    double g = 0.1; // g = 0.1000000000000000055511151231257827021181583404541015625
    assert(f != g); // different values
}

Ссылки

  • Стандарт 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)

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

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/operator_comparison

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API