名稱空間
變體
操作

比較運算子

來自 cppreference.com
< 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,其值(不是左值)在指定關係為真時為 1,在指定關係不為真時為 0

如果 lhsrhs 都是任何實數型別的表示式,則

  • 執行常用算術轉換
  • 轉換後的運算元的值按通常的數學意義進行比較(正零和負零比較相等,任何涉及 NaN 值的比較返回零)

請注意,複數和虛數不能用這些運算子進行比較。

如果 lhsrhs 都是指標型別的表示式,則它們必須都是指向相容型別物件的指標,但忽略所指向物件的限定符。

  • 指向不是陣列元素的物件的指標被視為指向只有一個元素的陣列的元素
  • 如果兩個指標指向同一個物件,或者都指向同一個陣列的末尾之後一個位置,則它們比較相等
  • 如果兩個指標指向同一個陣列的不同元素,則指向索引較大的元素的指標比較大。
  • 如果一個指標指向陣列的元素,而另一個指標指向同一個陣列的末尾之後一個位置,則指向末尾之後一個位置的指標比較大
  • 如果兩個指標指向同一個結構體的成員,則指向在結構體定義中宣告在後面的成員的指標比較大,而不是指向在前面宣告的成員的指標。
  • 指向同一聯合體成員的指標比較相等
  • 所有其他指標比較都會導致未定義行為
#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 - 表示式,它們
(自 C23 起)
  • 都是指向物件或函式的相容型別的指標,忽略所指向型別的限定符
  • 一個是指向物件的指標,另一個是指向(可能受限定的)void 的指標
  • 一個是指向物件或函式的指標,另一個是空指標常量,例如 NULL nullptr(C23 起)

任何相等運算子表示式的型別都是 int,其值(不是左值)在指定關係為真時為 1,在指定關係不為真時為 0

  • 如果兩個運算元都具有算術型別,則執行常用算術轉換,並按通常的數學意義比較結果值(正零和負零比較相等,任何涉及 NaN 值的比較,包括與自身的相等比較,都返回零)。特別是,如果複數型別的實部比較相等且虛部比較相等,則它們相等。
(自 C23 起)
  • 如果一個運算元是指標,另一個是空指標常量,則空指標常量首先轉換為指標的型別(這會給出空指標值),然後按如下所述比較這兩個指標
  • 如果一個運算元是指標,另一個是指向 void 的指標,則非 void 指標轉換為指向 void 的指標,然後按如下所述比較這兩個指標
  • 如果滿足以下任何條件,則兩個指標比較相等
  • 它們都是其型別的空指標值
  • 它們都指向同一個物件或函式
  • 一個指標指向結構體/聯合體/陣列物件,另一個指標指向其第一個成員/任何成員/第一個元素
  • 它們都指向同一個陣列的最後一個元素之後一個位置
  • 一個指標指向陣列的末尾之後一個位置,另一個指標指向在較大陣列中或沒有填充的結構體中緊隨第一個陣列的不同陣列(相同型別)的開頭

(與關係運算符一樣,指向不是任何陣列元素的物件的指標的行為與指向大小為 1 的陣列元素的指標相同)

[編輯] 註釋

結構體型別的物件不會自動比較相等,並且使用 memcmp 比較它們並不可靠,因為填充位元組可能具有任何值。

由於指標比較適用於指向 void 的指標,宏 NULL 在 C 語言中可以定義為 (void*)0,儘管這在 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 關係運算符 (p: 68-69)
  • 6.5.9 相等運算子 (p: 69-70)
  • C11 標準 (ISO/IEC 9899:2011)
  • 6.5.8 關係運算符 (p: 95-96)
  • 6.5.9 相等運算子 (p: 96-97)
  • C99 標準 (ISO/IEC 9899:1999)
  • 6.5.8 關係運算符 (p: 85-86)
  • 6.5.9 相等運算子 (p: 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 起)
(直至 C23)

alignof
(自 C23 起)

C++ 文件,關於比較運算子