Comparison operators
比較演算子は条件をテストする二項演算子であり、その条件が論理的に 1 を返し、その条件が 0 を返す場合に true と false となります。
| 演算子 | 演算子名 | 例 | 説明 |
|---|---|---|---|
| == | 等しい | 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値を含むあらゆる比較はゼロを返す)
複素数と虚数はこれらの演算子で比較できないことに注意してください。
lhs と rhs がポインタ型の式である場合、これらは両方とも 互換性のある型 のオブジェクトへのポインタでなければなりません。ただし、指し示されるオブジェクトの修飾子は無視されます。
- 配列の要素ではないオブジェクトへのポインタは、1つの要素を持つ配列の要素を指しているかのように扱われる
- 2つのポインタが同じオブジェクトを指している場合、または両方が同じ配列の末尾を超えた位置を指している場合、それらは等しいと比較される
- 2つのポインタが同じ配列の異なる要素を指している場合、より大きいインデックスの要素を指すポインタがより大きいと比較される
- 一方のポインタが配列の要素を指し、もう一方のポインタが同じ配列の末尾を超えた位置を指している場合、末尾を超えた位置を指すポインタがより大きいと比較される
- 2つのポインタが同じ struct のメンバを指している場合、struct定義で後に宣言されたメンバを指すポインタが、先に宣言されたメンバを指すポインタより大きいと比較される
- 同じunionのメンバへのポインタは等しいと比較される
- その他のすべてのポインタ比較は未定義動作を引き起こす
#include <assert.h> int main(void) { assert(1 < 2); assert(2+2 <= 4.0); // intからdoubleへの変換、2つの4.0が等しいと比較される struct { int x,y; } s; assert(&s.x < &s.y); // 構造体メンバは宣言順に比較される 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); // 異なる値 }
等価演算子
等価演算子の式は以下の形式を持ちます
lhs
==
rhs
|
(1) | ||||||||
lhs
!=
rhs
|
(2) | ||||||||
タグ内のテキスト(==, !=)はC++演算子のため非翻訳
- lhs, rhsはC++の標準的な用語(左辺値、右辺値)のため非翻訳
- 数値の(1)、(2)は番号表記のため非翻訳
等価演算子式の型は int であり、その値(左辺値ではない)は 1 が指定された関係が真の場合であり、 0 が指定された関係が成立しない場合です。
- 両方のオペランドが算術型を持つ場合、 通常の算術変換 が実行され、結果の値は通常の数学的な意味で比較されます(ただし、正のゼロと負のゼロは等しいと比較され、NaN値を含むあらゆる比較、それ自体との等価性を含む、はゼロを返します)。特に、複素数型の値は、それらの実数部が等しく比較され、かつそれらの虚数部が等しく比較される場合に等しくなります。
| (C23以降) |
- 一方のオペランドがポインタで、もう一方がヌルポインタ定数の場合、ヌルポインタ定数はまず 変換 されてポインタの型になり(これによりヌルポインタ値が得られる)、その後以下のように二つのポインタが比較される
- 一方のオペランドがポインタで、もう一方がvoidへのポインタの場合、非voidポインタは 変換 されてvoidへのポインタになり、その後以下のように二つのポインタが比較される
- 以下のいずれかの条件が真の場合、二つのポインタは等しいと比較される:
-
- 両方ともその型のヌルポインタ値である
- 両方とも同じオブジェクトまたは関数を指している
- 一方のポインタが構造体/共用体/配列オブジェクトを指し、他方がその最初のメンバー/任意のメンバー/最初の要素を指している
- 両方とも同じ配列の最後の要素の次を指している
- 一方が配列の終端の次を指しており、他方が(同じ型の)別の配列の先頭を指しており、その配列が最初の配列に続いて配置されている(より大きな配列内またはパディングのない構造体内)
(関係演算子と同様に、配列の要素ではないオブジェクトへのポインタは、サイズ1の配列の要素へのポインタとして振る舞う)
注記
struct型のオブジェクトは自動的には等価比較されず、 memcmp による比較は信頼できません。なぜならパディングバイトは任意の値を持つ可能性があるためです。
ポインタ比較はvoidへのポインタでも機能するため、マクロ NULL はC言語では ( void * ) 0 と定義されることがあります。ただし、これはC++では無効です。C++ではvoidポインタは型付きポインタに暗黙的に変換されないためです。
浮動小数点値の等価性を比較する際には注意が必要です。なぜなら、多くの演算結果は正確に表現できず、丸められる必要があるためです。実際には、浮動小数点数は通常、最後の桁の1つ以上の単位の差を許容して比較されます。
#include <assert.h> int main(void) { assert(2+2 == 4.0); // intからdoubleへの変換、2つの4.0が等しいと比較される int n[2][3] = {1,2,3,4,5,6}; int* p1 = &n[0][2]; // 最初の行の最後の要素 int* p2 = &n[1][0]; // 2行目の開始位置 assert(p1+1 == p2); // 等しいと比較される double d = 0.0/0.0; // NaN assert( d != d ); // NaNは自身と等しくない float f = 0.1; // f = 0.100000001490116119384765625 double g = 0.1; // g = 0.1000000000000000055511151231257827021181583404541015625 assert(f != g); // 異なる値 }
参考文献
- 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++ documentation
for
Comparison operators
|