Comparison operators
Операторы сравнения - это бинарные операторы, которые проверяют условие и возвращают 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) | ||||||||
` или является техническими идентификаторами
Структура таблицы и форматирование полностью сохранены.
где
| 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) | ||||||||
где
| lhs , rhs | - |
выражения, которые
|
Тип любого выражения оператора равенства — int , а его значение (не являющееся lvalue) равно 1 , когда указанное отношение выполняется, и 0 , когда указанное отношение не выполняется.
- если оба операнда имеют арифметические типы, обычные арифметические преобразования выполняются, и полученные значения сравниваются в обычном математическом смысле (за исключением того, что положительные и отрицательные нули считаются равными, а любое сравнение с участием значения NaN, включая равенство с самим собой, возвращает ноль). В частности, значения комплексного типа равны, если их действительные части равны и их мнимые части равны.
| (начиная с 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
|
+
a
|
!
a
|
a
==
b
|
a
[
b
]
|
a
(
...
)
|
|
C++ документация
для
Операторов сравнения
|