Comparison operators
比较运算符是二元运算符,用于测试条件,若条件逻辑为 真 则返回 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 |
目录 |
关系运算符
关系运算符表达式的形式为
左操作数
<
右操作数
|
(1) | ||||||||
左操作数
>
右操作数
|
(2) | ||||||||
左操作数
<=
右操作数
|
(3) | ||||||||
左操作数
>=
右操作数
|
(4) | ||||||||
其中
| lhs , rhs | - | 两个表达式均具有实数类型或均具有指向对象类型的指针 |
任何关系运算符表达式的类型为 int ,其值(非左值)在指定关系成立时为 1 ,在指定关系不成立时为 0 。
如果 lhs 和 rhs 是任意 实数类型 的表达式,则
- 执行 常规算术转换
- 转换后的操作数值按常规数学意义进行比较(正负零比较结果相等,涉及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) | ||||||||
标签内的运算符均未翻译,C++术语lhs/rhs保留原样,仅对结构编号添加了中文括号)
任何相等运算符表达式的类型为 int ,其值(非左值)在指定关系成立时为 1 ,在指定关系不成立时为 0 。
- 若两个操作数均具有算术类型,则执行 常规算术转换 ,并按常规数学意义比较结果值(但正负零比较相等,任何涉及NaN值的比较(包括与自身的相等性比较)均返回零)。特别地,若复数类型的实部比较相等且虚部比较相等,则这两个复数值相等。
| (since C23) |
- 如果一个操作数是指针而另一个是空指针常量,该空指针常量首先 转换 为指针类型(得到空指针值),然后按以下规则比较两个指针
- 如果一个操作数是指针而另一个是void指针,非void指针将 转换 为void指针,然后按以下规则比较两个指针
- 满足以下任意条件时,两个指针比较结果相等:
-
- 它们都是各自类型的空指针值
- 它们都指向同一对象或函数
- 一个指针指向结构体/联合体/数组对象,另一个指针指向其首成员/任意成员/首元素
- 它们都指向同一数组的末元素后一位置
- 一个指针指向某数组的末元素后一位置,另一个指针指向紧随其后的同类型数组(位于更大数组或无填充结构体中)的首元素位置
(与关系运算符类似,指向非任何数组元素的对象的指针,其行为如同指向大小为1的数组元素的指针)
注释
结构体类型的对象不会自动进行相等比较,使用 memcmp 进行比较也不可靠,因为填充字节可能包含任意值。
由于指针比较适用于指向 void 的指针,在 C 语言中宏 NULL 可被定义为 ( void * ) 0 ,但在 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 关系运算符 (p: 68-69)
-
- 6.5.9 相等运算符 (p: 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++ 文档
关于
比较运算符
|