名前空間
変種
操作

比較演算子

From cppreference.com
< c‎ | language

比較演算子は、条件をテストし、その条件が論理的にであれば1であれば0を返す二項演算子です。

Operator 演算子名 説明
== 等しい a == b ab と等しい
!= 等しくない a != b ab と等しくない
< より小さい a < b ab より小さい
> より大きい a > b ab より大きい
<= 以下 a <= b ab 以下である
>= 以上 a >= b ab 以上である

目次

[編集] 関係演算子

関係演算子の式は次の形式をとります。

lhs < rhs (1)
lhs > rhs (2)
lhs <= rhs (3)
lhs >= rhs (4)
1) より小さい式
2) より大きい式
3) 以下である式
4) 以上である式

ここで、

lhs, rhs - 実数型またはオブジェクト型へのポインタ型を両方とも持つ式

任何関係演算子式 (operator expression) の型は int であり、その値(lvalue ではない)は、指定された関係が真である場合は 1、指定された関係が偽である場合は 0 となります。

もし lhsrhs が任意の 実数型 の式である場合、

  • 通常の算術変換が実行されます。
  • 変換後のオペランドの値が通常の数学的意味で比較されます(ただし、正のゼロと負のゼロは等しく比較され、NaN 値を含む比較はすべてゼロを返します)。

複素数と虚数はこれらの演算子で比較できないことに注意してください。

lhsrhs がポインタ型の式である場合、それらは両方とも 互換性のある型 のオブジェクトへのポインタでなければなりません。ただし、ポインタ先のオブジェクトの修飾子は無視されます。

  • 配列の要素ではないオブジェクトへのポインタは、サイズ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)
1) 等しい式
2) 等しくない式

ここで、

lhs, rhs - 式で、
  • 両方とも任意の 算術型(複素数および虚数を含む)を持つ。
  • nullptr_t 型を両方とも持つ。
  • 一方が nullptr_t 型で、もう一方がヌルポインタ定数である。
(C23以降)
  • 両方とも 互換性のある 型のオブジェクトまたは関数のポインタであり、ポインタ先の型の修飾子は無視される。
  • 一方がオブジェクトへのポインタで、もう一方が(修飾されている可能性のある) void へのポインタである。
  • 一方がオブジェクトまたは関数のポインタで、もう一方がヌルポインタ定数(例:NULL または nullptr(C23以降))である。

任何等値演算子式 (equality operator expression) の型は int であり、その値(lvalue ではない)は、指定された関係が真である場合は 1、指定された関係が偽である場合は 0 となります。

  • 両方のオペランドが算術型を持つ場合、通常の算術変換が実行され、結果の値が通常の数学的意味で比較されます(ただし、正のゼロと負のゼロは等しく比較され、NaN 値との比較(自身との等号比較を含む)はすべてゼロを返します)。特に、複素数型の値は、実部が等しく、虚部が等しい場合に等しいとみなされます。
  • 2つの nullptr_t 値、または1つの nullptr_t 値とヌルポインタ定数は等しく比較されます。
(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 += 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++ ドキュメント比較演算子
English 日本語 中文(简体) 中文(繁體)