Операторы сравнения
Операторы сравнения — это бинарные операторы, которые проверяют условие и возвращают 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) |
где
| 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) |
где
| lhs, rhs | - | выражения, которые
|
Тип любого выражения с оператором равенства — int, а его значение (которое не является lvalue) — 1, когда указанное отношение истинно, и 0, когда указанное отношение ложно.
- если оба операнда имеют арифметические типы, выполняются обычные арифметические преобразования, и полученные значения сравниваются в обычном математическом смысле (за исключением того, что положительные и отрицательные нули сравниваются как равные, и любое сравнение, включающее значение NaN, в том числе сравнение с самим собой, возвращает ноль). В частности, значения комплексного типа равны, если их вещественные части сравниваются как равные, а их мнимые части сравниваются как равные.
| (с 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 Операторы равенства
См. также
| Общие операторы | ||||||
|---|---|---|---|---|---|---|
| присваивание | инкремент декремент | арифметические | логические | сравнения | доступ к членам объекта | другие |
|
|
|
|
|
|
|
|
| Документация C++ для Операторы сравнения |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/operator_comparison