命名空間
變體
動作

比較運算子

出自 cppreference.com
< c‎ | 語言

比較運算子是二元運算子,用於測試條件,若條件在邏輯上為「真」(true)則回傳 1,若為「假」(false)則回傳 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 值的比較皆回傳 0)

請注意,複數與虛數無法使用這些運算子進行比較。

lhsrhs 為指標類型的運算式,它們必須皆是指向相容類型物件的指標,唯指向物件的限定符(qualifiers)會被忽略。

  • 指向非陣列元素之物件的指標,會被視為指向一個大小為 1 之陣列元素的指標
  • 若兩個指標指向同一個物件,或是皆指向同一個陣列末端之後的一個位置,則視為相等
  • 若兩個指標指向同一個陣列的不同元素,則指向索引較大元素的指標為大。
  • 若其中一個指標指向陣列的元素,另一個指標指向同一個陣列末端之後的一個位置,則指向末端之後位置的指標為大
  • 若兩個指標指向同一個 struct 的成員,則結構定義中宣告順序在後者的成員指標較大。
  • 指向同一個 union 成員的指標視為相等
  • 所有其他指標比較皆會引發未定義行為
#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 - 這些運算式要求:
  • 兩者皆具有任何算術類型(包含複數與虛數)
  • 兩者皆為 nullptr_t 類型
  • 其中一個為 nullptr_t 類型,另一個為空指標常數
(C23 起)
  • 兩者皆是指向相容類型物件或函式的指標,忽略指向類型的限定符
  • 其中一個是指向物件的指標,另一個是指向(可能帶有限定符的) void 的指標
  • 其中一個是指向物件或函式的指標,另一個是諸如 NULL nullptr(自 C23 起) 之類的空指標常數

任何相等運算子運算式的類型皆為 int,且當指定的關係成立時,其值(非左值)為 1,反之則為 0

  • 若兩個運算元皆為算術類型,則進行一般算術轉換,並以一般數學意義比較其結果值(例外:正零與負零視為相等,且任何涉及 NaN 值的比較,包含與自身比較,皆回傳 0)。特別是,當複數的實部與虛部各自相等時,則視為相等。
  • 兩個 nullptr_t 值,或一個 nullptr_t 值與一個空指標常數比較時視為相等
(C23 起)
  • 若其中一個運算元是指標,另一個是空指標常數,則空指標常數會先被轉換為該指標類型(得到一個空指標值),然後再如以下所述進行指標比較
  • 若其中一個運算元是指標,另一個是指向 void 的指標,則非 void 指標會被轉換為指向 void 的指標,然後再如以下所述進行比較
  • 在以下情況下,兩個指標視為相等:
  • 兩者皆為各自類型的空指標值
  • 兩者皆指向同一個物件或函式
  • 其中一個指標指向 struct/union/陣列物件,另一個指向其第一個成員/任何成員/第一個元素
  • 兩者皆指向同一個陣列最後一個元素之後的位置
  • 一個指向某陣列末端之後的位置,另一個指向接續在前一個陣列之後(在更大的陣列中或無填充的 struct 中)的另一個陣列(相同類型)的開頭

(與關係運算子相同,指向非陣列元素之物件的指標,表現為指向大小為 1 之陣列元素的指標)

[編輯] 備註

Struct 類型的物件不會自動比較相等,且使用 memcmp 進行比較不可靠,因為填充位元組(padding bytes)可能包含任何值。

由於指標比較適用於指向 void 的指標,因此在 C 語言中宏 NULL 可定義為 (void*)0,但在 C++ 中這將無效,因為 C++ 不允許 void 指標隱式轉換為具類型的指標。

在比較浮點數是否相等時必須小心,因為許多運算的結果無法精確表示,必須進行捨入。在實務上,比較浮點數時通常會允許一個或多個最後一位單位(ULP)的誤差。

#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
(型別) a
a ? b : c
sizeof


_Alignof
(自 C11 起)
(C23 之前)

alignof
(C23 起)

C++ 文件比較運算子
English Deutsch 日本語 中文(简体) 中文(繁體)