Comparison operators
비교 연산자는 조건을 검사하는 이항 연산자로, 해당 조건이 논리적으로 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) | ||||||||
태그 내부의 C++ 연산자 및 lhs/rhs 용어는 번역하지 않고 원본을 유지했습니다. 표의 구조와 서식도 완벽하게 보존되었습니다.
여기서
| lhs , rhs | - | 둘 다 실수 타입을 가지거나 둘 다 객체 포인터 타입을 가지는 표현식들 |
모든 관계 연산자 표현식의 타입은 int 이며, 그 값(좌측값이 아님)은 1 입니다. 이는 지정된 관계가 성립할 때이며, 0 은 지정된 관계가 성립하지 않을 때입니다.
만약 lhs 와 rhs 가 실수 타입 의 어떤 표현식이라면,
- usual arithmetic conversions 이 수행됩니다
- 변환 후 피연산자 값들은 일반적인 수학적 의미로 비교됩니다 (단, 양의 영과 음의 영은 동일하게 비교되며 NaN 값을 포함하는 모든 비교는 0을 반환합니다)
복소수와 허수는 이러한 연산자로 비교할 수 없습니다.
만약 lhs 와 rhs 가 포인터 타입의 표현식이라면, 이들은 모두 호환 가능한 타입 의 객체를 가리키는 포인터여야 합니다. 단, 가리키는 객체의 한정자(qualifications)는 무시됩니다.
- 배열의 요소가 아닌 객체에 대한 포인터는 요소가 하나인 배열의 요소를 가리키는 것처럼 취급됩니다
- 두 포인터가 동일한 객체를 가리키거나, 둘 다 동일한 배열의 끝 다음을 가리키는 경우 동일하게 비교됩니다
- 두 포인터가 동일한 배열의 서로 다른 요소를 가리키는 경우, 더 큰 인덱스를 가진 요소를 가리키는 포인터가 더 큰 것으로 비교됩니다
- 한 포인터가 배열의 요소를 가리키고 다른 포인터가 동일한 배열의 끝 다음을 가리키는 경우, 끝 다음을 가리키는 포인터가 더 큰 것으로 비교됩니다
- 두 포인터가 동일한 struct 의 멤버를 가리키는 경우, struct 정의에서 나중에 선언된 멤버를 가리키는 포인터가 먼저 선언된 멤버를 가리키는 포인터보다 더 큰 것으로 비교됩니다
- 동일한 union의 멤버에 대한 포인터는 동일하게 비교됩니다
- 다른 모든 포인터 비교는 정의되지 않은 동작을 유발합니다
#include <assert.h> int main(void) { assert(1 < 2); assert(2 + 2 <= 4.0); // int가 double로 변환, 두 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, ==, !=)는 번역하지 않고 원형을 유지했습니다. 표의 구조와 서식도 완전히 보존되었습니다.
여기서
| lhs , rhs | - |
다음 조건을 만족하는 표현식들
|
모든 동등 연산자 표현식의 타입은 int 이며, 그 값(좌측값이 아님)은 1 입니다. 이는 지정된 관계가 참일 때이며, 0 은 지정된 관계가 성립하지 않을 때입니다.
- 두 피연산자가 모두 산술 타입을 가지고 있다면, 일반 산술 변환 이 수행되고 결과 값들은 일반적인 수학적 의미로 비교됩니다(단, 양의 영과 음의 영은 동일하게 비교되며 NaN 값을 포함하는 모든 비교, 심지어 자기 자신과의 동등 비교도 0을 반환합니다). 특히, 복소수 타입의 값들은 실수 부분이 동일하게 비교되고 허수 부분이 동일하게 비교될 때 동등합니다.
| (C23 이후) |
- 한쪽 피연산자가 포인터이고 다른 쪽이 null 포인터 상수인 경우, null 포인터 상수가 먼저 변환되어 포인터 타입이 된 후(이렇게 하면 null 포인터 값이 생성됨), 두 포인터는 아래에 설명된 방식으로 비교됩니다
- 한쪽 피연산자가 포인터이고 다른 쪽이 void 포인터인 경우, non-void 포인터가 변환되어 void 포인터가 된 후 두 포인터는 아래에 설명된 방식으로 비교됩니다
- 다음 중 어느 하나에 해당하는 경우 두 포인터는 동일한 것으로 비교됩니다:
-
- 둘 다 해당 유형의 널 포인터 값인 경우
- 둘 다 동일한 객체나 함수를 가리키는 포인터인 경우
- 한 포인터가 struct/union/array 객체를 가리키고 다른 포인터가 해당 객체의 첫 번째 멤버/임의의 멤버/첫 번째 요소를 가리키는 경우
- 둘 다 동일한 배열의 마지막 요소 바로 다음을 가리키는 경우
- 하나가 배열의 끝 바로 다음을 가리키고, 다른 하나가 더 큰 배열 내에서 첫 번째 배열 뒤에 오는 다른 배열(동일한 유형)의 시작 부분을 가리키거나 패딩이 없는 구조체 내에서 이어지는 경우
(관계 연산자와 마찬가지로, 어떤 배열의 요소가 아닌 객체에 대한 포인터는 크기 1의 배열 요소에 대한 포인터처럼 동작합니다)
참고 사항
구조체 타입의 객체는 자동으로 동일하게 비교되지 않으며, memcmp 로 비교하는 것은 패딩 바이트가 어떤 값이든 가질 수 있기 때문에 신뢰할 수 없습니다.
void 포인터에 대한 포인터 비교가 작동하기 때문에, 매크로 NULL 는 C 언어에서 ( void * ) 0 로 정의될 수 있습니다. 비록 이것은 void 포인터가 타입이 지정된 포인터로 암시적으로 변환되지 않는 C++에서는 유효하지 않을 것입니다.
부동 소수점 값을 동등성 비교할 때는 주의해야 합니다. 많은 연산의 결과가 정확하게 표현될 수 없으며 반올림되어야 하기 때문입니다. 실제로는 부동 소수점 숫자를 비교할 때 보통 최하위 비트(ULP) 하나 이상의 차이를 허용합니다.
#include <assert.h> int main(void) { assert(2+2 == 4.0); // 정수가 double로 변환, 두 4.0이 동일하게 비교됨 int n[2][3] = {1,2,3,4,5,6}; int* p1 = &n[0][2]; // 첫 번째 행의 마지막 요소 int* p2 = &n[1][0]; // 두 번째 행의 시작 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++ 문서
for
Comparison operators
|