[Java의 정석]제3장 연산자 - 4.비교연산자, 5.그 외의 연산자

류명운

·

2014. 7. 3. 22:25

반응형

4. 비교 연산자


두 개의 변수 또는 리터럴을 비교하는 데 사용되는 연산자로, 주로 조건문과 반복문의 조건식에 사용되며, 연산결과는 true 또는 false이다.
비교연산자 역시 이항연산자이므로 비교하는 피연산자의 자료형이 서로 다를 경우에는 자료형의 범위가 큰 쪽으로 형변환을 하여 피연산자의 타입을 일치시킨 후에 비교한다.


4.1 대소비교연산자 - <, >, <=, >=

두 피연산자의 크기를 비교하는 연산자이다. 기본형 중에서는 boolean형을 제외한 나머지 자료형에 다 사용할 수 있고, 참조형에는 사용할 수 없다.



4.2 등가비교연산자 - ==, !=

두 피연산자에 저장되어 있는 값이 같은지, 또는 다른지를 비교하는 연산자이다.
대소비교연산자(<,>, <=, >=)와는 달리, 기본형은 물론 참조형 모든 자료형에 사용할 수 있다. 기본형의 경우 변수에 저장되어 있는 값이 같은지를 알 수 있고, 참조형의 경우 객체의 주소값을 저장하기 때문에 두 개의 피연산자(참조변수)가 같은 객체를 가리키고 있는지를 알 수 있다.
기본형과 참조형간에는 서로 형변환이 가능하지 않기 때문에 등가비교 연산자(==,!=)의 피연산자로 기본형과 참조형을 함께 사용할 수는 없다.

[참고] 참조형 변수에 사용할 수 있는 연산자는 "=="와 "!=" 그리고 캐스트 연산자 뿐이다. String에는 예외적으로 문자열결합에 "+"을 사용하는 것을 허용한다.



[예제3-21] OperatorEx21.java

class OperatorEx21
{
public static void main(String[] args)
{
if(10 == 10.0f) {
System.out.println("10과 10.0f은 같다.");
}

if('0' != 0) {
System.out.println("'0'과 0은 같지 않다.");
}

if('A' == 65) {
System.out.println("\"A\"는 65와 같다.");
}

int num = 5;

if( num > 0 && num < 9) {
System.out.println("5는 0보다 크고, 9보다는 작다.");
}
}
}
[실행결과]
10과 10.0f은 같다.
'0'과 0은 같지 않다.
'A'는 65와 같다.
5는 0보다 크고, 9보다는 작다.

비교연산자에서도 연산을 수행하기 전에 형변환을 통해 피연산자의 타입을 맞춘 다음 피연산자를 비교한다. 10==10.0f에서 10은 int이고 10.0f는 float이므로, int값인 10을 보다 큰 범위를 갖는 float로 변환한 다음 비교한다. 두 값이 10.0f로 같으므로 결과로 true를 얻게 된다.
마찬가지로 'A'==65는 'A'가 int로 변환되어 65가 된 다음 65==65를 계산하므로 역시 true를 얻는다.
[참고]문자 'A'의 문자코드는 10진수로 65이다.





4.3 비트 연산자 - &, |, ^

비트 연산자는 이진 비트연산을 수행한다. 값을 이진수로 표현했을 때의 각 자리수를 아래의 표의 규칙에 따라 연산을 수행한다. 실수형인 float와 double을 제외한 모든 기본형에 사용가능 하다.


|(OR연산자) - 피연산자 중 한 쪽의 값이 1이면, 1을 결과로 얻는다. 그 외에는 0을 얻는다.
&(AND연산자) - 피연산자 양 쪽이 모두 1이어야 1을 결과로 얻는다. 그 외에는 0을 얻는다.
^(XOR연산자) - 피연산자의 값이 서로 다를 때만 1을 결과로 얻는다. 같을 때는 0을 얻는다.


[참고]boolean형의 경우 1은 true로 0은 false로 생각하면 된다. 예를 들면 true & true의 연산결과는 true이고 true ^false의 결과는 true이다.
[참고]연산자 "^"는 배타적 OR(Exclusive OR)라고 하며, 피연산자의 값이 서로 다른 경우, 즉 배타적인 경우에만 1 또는 true를 결과로 얻는다.


[예제3-22] OperatorEx22.java

class OperatorEx22
{
public static void main(String[] args)
{
int x = 3;
int y = 5;
System.out.println("x는 " + x + "이고, y는 " + y +"일 때, ");
System.out.println("x | y = " + (x|y));
System.out.println("x & y = " + (x&y));
System.out.println("x ^ y = " + (x^y));

System.out.println("true | false = " + (true|false));
System.out.println("true & false = " + (true&false));
System.out.println("true ^ false = " + (true^false));
}
}
[실행결과]
x는 3이고, y는 5일 때,
x | y = 7
x & y = 1
x ^ y = 6
true | false = true
true & false = false
true ^ false = true

[참고]비트연산자는 덧셈연산자(+)보다 연산우선순위가 낮기 때문에 괄호를 사용해야한다.




5. 그 외의 연산자

5.1 논리연산자 - &&, ||

논리 연산자는 피연산자로 boolean형 또는 boolean형 값을 결과로 하는 조건식만을 허용한다. 조건문과 반복문에서 조건식간의 결합에 사용된다.
그리고, "&&"가 "||" 연산보다 우선순위가 높으므로 한 조건식에 "&&"와 "||" 가 함께 사용될 때는 괄호를 사용해서 우선순위를 명확히 해주는 것이 좋다.


|| (OR결합) - 피연산자 중 한 쪽만 true이면 true을 결과로 얻는다.
&&(AND결합) - 피연산자 양쪽 모두 true이어야 true을 결과로 얻는다.




논리연산자의 또 다른 특징은 효율적인 연산을 한다는 것이다. OR연산(||)의 경우, 두 개의 피연산자중 어느 한 쪽만 true이어도 전체 연산결과가 true이므로 좌측의 피연산자가 true이면, 우측의 피연산자의 값은 검사하지 않는다. AND연산(&&)의 경우도 마찬가지로 어느 한쪽만 false이어도 전체 연산결과가 false이므로 좌측의 피연산자가 false이면, 우측의 피연산자의 값은 검사하지 않는다.
같은 조건식이라도 피연산자의 위치에 따라서 연산속도가 달라질 수 있는 것이다. AND연산의 경우에는 연산결과가 false일 확률이 높은 피연산자를 연산자의 좌측에 놓아야 더 빠른 연산결과를 얻을 수 있을 것이다.

[참고]비트연산자 "|"와 "&" 역시 피연산자로 boolean형을 허용하므로 조건식간의 연결에 사용할 수 있지만, "||"나 "&&"와는 달리 항상 양 쪽의 피연산자를 모두 검사한다.

[예제3-23] OperatorEx23.java

class OperatorEx23
{
public static void main(String[] args)
{
char x='j';

if((x>='a' && x <='z') || (x>='A' && x <='Z')) {
System.out.println("유효한 문자입니다.");
} else {
System.out.println("유효하지 않은 문자입니다.");
}
}
}
[실행결과]
유효한 문자입니다.

"&&"와 "||"를 조합하여 문자 x가 영문자인지를 검사하는 조건식을 만들었다. 사용자로부터 입력받은 문자를 검사하는데 응용될 수 있을 것이다. 대문자보다 소문자를 입력할 확률이 높기 때문에 소문자인지를 검사하는 식을 좌측에 두었다.
문자형 변수 x에 저장된 문자가 'j'이므로 OR연산자(||)의 좌측 피연산자인 조건식(x>='a' && x <='z')의 결과가 true이다. 그래서 나머지 우측 피연산자는 검사하지 않고 전체 조건식을 true로 판단한다.

[참고]영문자 또는 숫자인지를 검사하려면 조건식을 ((x>='a' && x <='z') || (x>='A' && x <='Z') || (x>='0' && x <='9'))와 같이 하면 된다.



5.2 삼항 연산자 - ? :

삼항 연산자는 세 개의 피연산자를 필요로 하기 때문에 삼항연산자로 이름지어졌다. 조건식과 조건식이 참(true)일 때와 거짓(false)일 때 반환되는 값 이 세가지가 삼항연산자의 피연산자이다. 삼항연산자의 조건식에는 연산결과가 true 또는 false인 식이 사용되어야 한다.
삼항연산자는 if문으로 바꿔 쓸 수 있으며, 간단한 if문 대신 삼항연산자를 사용하면 코드를 보다 간단히 할 수 있다.
조건식의 연산결과가 true이면 식1을 결과로 얻고 false이면 식2를 결과로 얻는다.



(조건식) ? 식1 : 식2

result = (x > 0) ? x : -x


삼항연산자를 if문으로 변경하면 아래와 같다.


if (x > 0) {
result = x;
} else {
result = -x;
}



[예제3-24] OperatorEx24.java

class OperatorEx24
{
public static void main(String[] args)
{
int x = 10;
int y = -10;

int absX = (x >=0) ? x : -x;
int absY = (y >=0) ? y : -y;

System.out.println("x=10일 때, x의 절대값은 "+absX);
System.out.println("y=-10일 때, y의 절대값은 "+absY);
}
}
[실행결과]
x=10일 때, x의 절대값은 10
y=-10일 때, y의 절대값은 10

삼항연산자를 이용해서 변수의 절대값을 구하는 예제이다. 삼항연산자 대신 조건문을 사용하면 다음과 같다.


int abs_x=0;

if (x > 0) {
abs_x = x;
} else {
abs_x = -x;
}

[참고] if문 안에 선언한 변수는 if문 내에서만 유효하므로 변수 abs_x를 if문 외부에 선언하였다.



5.3 대입 연산자 - =, op=

대입연산자는 변수에 값 또는 수식의 연산결과를 저장하는데 사용된다. 대입연산자의 왼쪽에는 반드시 변수가 위치해야하며, 오른쪽에는 리터럴이나 변수 또는 수식이 올 수 있다.


int i = 0;
i = 3;
i = i + 3;
3 = i + 3; // 대입연산자의 왼쪽 피연산자가 변수가 아니다.
final MAX = 3;
MAX = 10; // 대입연산자의 왼쪽 피연산자가 변수가 아니다.


대입 연산자는 모든 연산자들 중에서 가장 낮은 연산순위를 가지고 있기 때문에 제일 마지막에 수행된다. 그리고 연산진행방향이 오른쪽에서 왼쪽이기 때문에 x=y=3;에서 y=3이 먼저 수행되고 그 다음에 x=y가 수행된다.

또한 대입연산자는 다른 연산자와 결합하여 "op="와 같은 방식으로 사용될 수 있다. 예를 들면, i = i + 3은 i +=3과 같이 표현될 수 있다.


반응형