比較運算子
比較運算子是二元運算子,用於測試條件,若條件在邏輯上為「真」(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) | ||||||||
其中
| lhs, rhs | - | 上述運算式的運算元皆為實數類型,或皆為物件指標類型 |
任何關係運算子運算式的類型皆為 int,且當指定的關係成立時,其值(非左值)為 1,反之則為 0。
若 lhs 與 rhs 為任何實數類型的運算式,則:
- 會進行一般算術轉換
- 轉換後的運算元值會以一般的數學意義進行比較(例外:正零與負零視為相等,且任何涉及 NaN 值的比較皆回傳 0)
請注意,複數與虛數無法使用這些運算子進行比較。
若 lhs 與 rhs 為指標類型的運算式,它們必須皆是指向相容類型物件的指標,唯指向物件的限定符(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) | ||||||||
任何相等運算子運算式的類型皆為 int,且當指定的關係成立時,其值(非左值)為 1,反之則為 0。
- 若兩個運算元皆為算術類型,則進行一般算術轉換,並以一般數學意義比較其結果值(例外:正零與負零視為相等,且任何涉及 NaN 值的比較,包含與自身比較,皆回傳 0)。特別是,當複數的實部與虛部各自相等時,則視為相等。
| (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 |
+a |
!a |
a == b |
a[b] |
a(...) |
| C++ 文件 之 比較運算子
|