비교 연산자

비교 연산자

비교 연산자도 오버로드할 수 있어요. 두 타입을 비교하거나, 기본 타입이 아닌 같은 타입의 값들을 비교할 때 유용하게 씁니다.

출처: 문서

본문

비교 연산자는 두 개의 서로 다른 타입을 비교하거나, 기본(basic) 타입이 아닌 같은 타입을 비교하도록 오버로드할 수 있어요. 연산자가 단순 타입이 아닌 경우, 비교 연산자의 결과 타입이 항상 boolean일 필요는 없어요. 다만 그럴 경우 if, repeat, while 문에서는 사용할 수 없습니다.

오버로드할 수 있는 비교 연산자는 다음과 같아요.

  • 같음(equal to)= 두 변수가 같은지 판별.
  • 다름(unequal to)<> 두 변수가 다른지 판별.
  • 작음(less than)< 한 변수가 다른 변수보다 작은지 판별.
  • 큼(greater than)> 한 변수가 다른 변수보다 큰지 판별.
  • 크거나 같음(greater than or equal to)>= 한 변수가 다른 변수보다 크거나 같은지 판별.
  • 작거나 같음(less than or equal to)<= 한 변수가 다른 변수보다 작거나 같은지 판별.

다름(<>) 연산자를 별도로 정의하지 않았다면, 컴파일러는 같음(=) 연산자를 사용해서 그 결과를 부정해 <>를 평가해요. 반대 방향은 성립하지 않아요. 즉 "equal to"가 없고 "unequal to"만 있을 때, 컴파일러는 같음(=) 표현식을 평가하기 위해 그걸 사용하지 않습니다.

예를 들어 다음 연산자는 두 개의 복소수를 비교할 수 있게 해 줘요.

operator = (z1, z2 : complex) b : boolean;

위 정의는 다음과 같은 형태의 비교를 가능하게 합니다.

Var
  C1,C2 : Complex;
begin
  If C1=C2 then
    Writeln('C1 and C2 are equal');
end;

비교 연산자 정의는 연산자가 비교하려는 타입을 가진 두 개의 매개변수가 필요해요. 여기서도 컴파일러는 교환 법칙을 적용하지 않으므로, 두 타입이 다르다면 비교 연산자를 두 개 정의해야 합니다. 복소수의 경우, complex가 먼저 오는 비교 하나와 real이 먼저 오는 비교 하나, 두 개를 정의해야 하는 거죠.

다음 정의가 있다고 할게요.

operator = (z1 : complex;r : real) b : boolean;
operator = (r : real; z1 : complex) b : boolean;

이제 다음 두 가지 비교가 가능해집니다.

Var
  R,S : Real;
  C : Complex;
begin
  If (C=R) or (S=C) then
   Writeln ('Ok');
end;

두 비교에서 realcomplex 타입의 순서가 뒤집혀 있는 점을 눈여겨보세요.

결과 타입은 boolean이 아니어도 돼요

다음 예시는 결과 타입이 boolean일 필요가 없다는 걸 보여줍니다.

Type
  TMyRec = record a,b : integer; end;
operator = (x,y : TMyRec) r : string;
begin
  if (x.a=y.a) and (x.b=y.b) then
    R:='equal'
  else
    R:='differ';
end;
var
  x,y : TMyRec;
begin
  x.a:=1;
  y.a:=1;
  Writeln(x=y);
  x.a:=2;
  y.a:=3;
  Writeln(x=y);
end.

실행하면 이 예시는 다음을 출력합니다.

equal
differ

당연히 if 문은 boolean 검사가 필요하므로, 이런 문장은 컴파일되지 않아요.

if (x=y) then
  writeln('Equal');

이 경우 컴파일러는 이런 오류를 냅니다.

Error: Incompatible types: got "ShortString" expected "Boolean"

더 알아보기