首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Comparison operators

比较运算符是测试条件的二元运算符,如果该条件为逻辑,则返回1,如果该条件为,则返回0

Operator

Operator name

Example

Description

==

equal to

a == b

a is equal to b

!=

not equal to

a != b

a is not equal to b

<

less than

a < b

a is less than b

greater than

a > b

a is greater than b

<=

less than or equal to

a <= b

a is less than or equal to b

=

greater than or equal to

a >= b

a is greater than or equal to b

关系运算符

关系运算符表达式具有这种形式。

lhs < rhs

(1)

lhs > rhs

(2)

lhs <= rhs

(3)

lhs >= rhs

(4)

1)少于表达式

2)大于表达式

3)较少或相等的表达

4)更大或相等的表达

其中

lhs, rhs

-

expressions that both have real type or both have pointer to object type

任何关系运算符表达式的类型是int,并且其值(不是左值)是1指定的关系成立并且​0​指定的关系不成立时的值。

如果 lhs 和 rhs 是任何实际类型的表达式,那么。

  • 如果 lhs 和 rhs 具有算术类型,则执行通常的算术转换
  • 转换后操作数的值以通常的数学意义进行比较(除了正数和负数比较相等且任何涉及 NaN 值的比较返回零)

请注意,复数和虚数不能与这些运算符进行比较。

如果lhs和rhs是指针类型的表达式,它们必须都是指向兼容类型对象的指针,只是指向对象的限定被忽略。

  • 指向不是数组元素的对象的指针被视为指向具有一个元素的数组元素
  • 如果两个指针指向同一个对象,或者两个指针都指向同一个数组的末尾,则它们会相等
  • 如果两个指针指向相同数组的不同元素,则指向索引较大的元素的指针比较大。
  • 如果一个指针指向一个数组的元素,另一个指针指向一个超过同一个数组的末尾,那么一个过去的末尾指针会比较大
  • 如果两个指针指向同一个结构体的成员,那么稍后在结构体定义中声明的成员指针比先前声明的成员的指针大。
  • 指向同一工会成员的指针相等
  • 所有其他指针比较都会调用未定义的行为
代码语言:javascript
复制
#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) );
 
    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

-

具有任何算术类型(包括复数和虚数)的表达式都是指向对象或兼容类型函数的指针,忽略指向类型的限定符一个是指向对象的指针,另一个是指向(可能限定的)void一个是指向对象或函数的指针,另一个是空指针常量,例如NULL

  • 两者都有算术类型(包括复数和虚数)
  • 都是指向兼容类型的对象或函数的指针,而忽略指向类型的限定符
  • 一个是指向对象的指针,另一个指向(可能合格的) void
  • 一个是指向对象或函数的指针,另一个是空指针常量,如 NULL

任何等号运算符表达式的类型是int,并且其值(不是左值)是1指定的关系成立并且​0​指定的关系不成立时的值。

  • 如果两个操作数都具有算术类型,则执行通常的算术转换,并以通常的数学意义对结果值进行比较(除了正数和负数比较相等并且任何涉及NaN值的比较,包括与其自身的相等性返回零)。特别是,如果复数类型的实部比较相等并且它们的虚部比较相等,则复数类型的值是相等的。
  • 如果一个操作数是一个指针而另一个是空指针常量,则空指针常量首先被转换为指针的类型(它给出一个空指针值),并且如下所述比较这两个指针
  • 如果一个操作数是一个指针,而另一个是指向 void 的指针,则非 void 指针转换为指向 void 的指针,并如下所述比较两个指针
  • 如果满足以下任一条件,则两个指针相等:
    • 它们都是它们类型的空指针值
    • 它们都是指向同一个对象的指针
    • 一个指针指向一个 struct / union / array 对象,另一个指向其第一个成员/任何成员/第一个元素
    • 他们都指向一个过去的同一阵列的最后一个元素
    • 一个是一个超过数组的末尾,另一个是不同数组的起始位置(相同类型),它跟随在较大数组中的第一个数组中,或者在没有填充的结构中

(与关系运算符一样,指向不是任何数组元素的对象的指针的行为就像指向大小为1的数组的元素的指针)。

注意

结构类型的对象不会自动比较相等,并且比较它们memcmp是不可靠的,因为填充字节可能有任何值。

由于指针比较与无效指针一起工作,因此NULL可以将宏定义为(void*)0C 语言,尽管在 C ++中无效指针不会隐式转换为类型指针。

在比较浮点值是否相等时必须小心,因为许多操作的结果不能精确表示,必须舍入。在实践中,通常会比较浮点数,以考虑最后一个地方的一个或多个单位的差异。

代码语言:javascript
复制
#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
}

参考

  • C11 standard (ISO/IEC 9899:2011):
    • 6.5.8 Relational operators (p: 95-96)
    • 6.5.9 Equality operators (p: 96-97)
  • C99 standard (ISO/IEC 9899:1999):
    • 6.5.8 Relational operators (p: 85-86)
    • 6.5.9 Equality operators (p: 86-87)
  • C89/C90 standard (ISO/IEC 9899:1990):
    • 3.3.8 Relational operators
    • 3.3.9 Equality operators

扫码关注腾讯云开发者

领取腾讯云代金券