比較演算子
比較演算子は、条件をテストし、その条件が論理的に真であれば1、偽であれば0を返す二項演算子です。
| Operator | 演算子名 | 例 | 説明 |
|---|---|---|---|
| == | 等しい | 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 | - | 実数型またはオブジェクト型へのポインタ型を両方とも持つ式 |
任何関係演算子式 (operator expression) の型は int であり、その値(lvalue ではない)は、指定された関係が真である場合は 1、指定された関係が偽である場合は 0 となります。
もし lhs と rhs が任意の 実数型 の式である場合、
- 通常の算術変換が実行されます。
- 変換後のオペランドの値が通常の数学的意味で比較されます(ただし、正のゼロと負のゼロは等しく比較され、NaN 値を含む比較はすべてゼロを返します)。
複素数と虚数はこれらの演算子で比較できないことに注意してください。
lhs と rhs がポインタ型の式である場合、それらは両方とも 互換性のある型 のオブジェクトへのポインタでなければなりません。ただし、ポインタ先のオブジェクトの修飾子は無視されます。
- 配列の要素ではないオブジェクトへのポインタは、サイズ1の配列の要素を指しているかのように扱われます。
- 2つのポインタが同じオブジェクトを指している場合、または両方とも同じ配列の末尾の1つ先を指している場合、それらは等しく比較されます。
- 2つのポインタが同じ配列の異なる要素を指している場合、より大きなインデックスの要素を指している方がより大きいと判断されます。
- 一方のポインタが配列の要素を指し、もう一方のポインタが同じ配列の末尾の1つ先を指している場合、末尾の1つ先のポインタの方が大きいと判断されます。
- 2つのポインタが同じ 構造体 のメンバーを指している場合、構造体定義で後で宣言されたメンバーへのポインタは、前で宣言されたメンバーへのポインタよりも大きいと判断されます。
- 同じ共用体のメンバーへのポインタは等しく比較されます。
- その他のポインタ比較は未定義の動作を呼び出します。
#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) | ||||||||
任何等値演算子式 (equality operator expression) の型は int であり、その値(lvalue ではない)は、指定された関係が真である場合は 1、指定された関係が偽である場合は 0 となります。
- 両方のオペランドが算術型を持つ場合、通常の算術変換が実行され、結果の値が通常の数学的意味で比較されます(ただし、正のゼロと負のゼロは等しく比較され、NaN 値との比較(自身との等号比較を含む)はすべてゼロを返します)。特に、複素数型の値は、実部が等しく、虚部が等しい場合に等しいとみなされます。
| (C23以降) |
- 一方がポインタで、もう一方がヌルポインタ定数である場合、ヌルポインタ定数はまずポインタの型に変換され(これによりヌルポインタ値が得られます)、その後、2つのポインタが以下のように比較されます。
- 一方がポインタで、もう一方が void へのポインタである場合、非 void ポインタは void へのポインタに変換され、その後、2つのポインタが以下のように比較されます。
- 2つのポインタが等しく比較されるのは、以下のいずれかが真の場合です。
- 両方とも、それぞれの型のヌルポインタ値である。
- 両方とも同じオブジェクトまたは関数を指している。
- 一方が構造体/共用体/配列オブジェクトへのポインタで、もう一方がその最初のメンバー/任意のメンバー/最初の要素へのポインタである。
- 両方とも同じ配列の末尾の1つ先を指している。
- 一方が配列の末尾の1つ先を指し、もう一方が、より大きな配列内またはパディングのない構造体内の、最初の配列の後に続く(同じ型の)別の配列の先頭を指している。
(関係演算子と同様に、どの配列の要素でもないオブジェクトへのポインタは、サイズ1の配列の要素へのポインタとして扱われます。)
[編集] 注釈
構造体型のオブジェクトは自動的に等しく比較されず、memcmp で比較しても、パディングバイトの値が不定であるため信頼できません。
ポインタ比較は void へのポインタでも機能するため、C ではマクロ NULL が (void*)0 として定義されることがありますが、これは void ポインタが型付きポインタに暗黙的に変換されない C++ では無効です。
浮動小数点値の等値比較には注意が必要です。なぜなら、多くの操作の結果は正確に表現できず、丸められる必要があるからです。実際には、浮動小数点数は通常、最後の桁の1つ以上の差を許容して比較されます。
#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++ ドキュメント (比較演算子)
|