Java

[Java] 논리 연산자와 그 외 연산자

seonggu 2022. 12. 8. 10:33

1️⃣ 논리 연산자 

논리 연산자 '&&'는 '그리고(AND)'에 해당하며, 두 피연산자가 모두 true일 때만 true를 결과로 얻는다. 
'||'는 '또는(OR)'에 해당하며, 두 피연산자 중 어느 한쪽만 true여도 true를 결과로 얻는다.

그리고 논리 연산자는 피연산자로 boolean형 또는 boolean형 값을 결과로 하는 조건식만을 허용한다.

💥 '|'는 한글 키보드에서 Enter키 위에 shift를 누른 상태에서 누르면 사용할 수 있다.

 

논리 연산자의 피연산자가 '참(true)인 경우'와 '거짓(false)인 경우'의 연산결과를 표로 나타내면,

x y x||y x&&y
true true true true
true false true false
false true true false
false false false false

일단은 책에서 활용된 예시들을 간단하게 정리하면 아래와 같이 사용하면 된다.

✅ ~~ 이고 ~~ 고 : && 

✅ 또는 : || 


헌데 예시 중 하나를 살펴보도록 하자. 

➡ i는 2의 배수 또는 3의 배수지만 6의 배수는 아니다.

이와 같은 경우는 논리 연산자를 어떻게 활용하여서 묶는 것이 좋을까?

 

일단 i는 2의 배수 또는 3의 배수를 작성하면,

i%2 == 0 || i%3 == 0

그리고 뒤에 나오는 6의 배수는 아니다를 작성하면,

i%6 != 0

마지막으로 ~~지만으로 묶여있으므로 &&(AND)로 묶어주면 된다.

(i%2 == 0 || i%3 == 0) && i%6 != 0

짚고 넘어갈 것이 있다면 괄호를 사용한 이유는 '&&'보다 '||'이 우선순위가 낮기 때문이다. 만일 괄호를 사용하지  않으면 '&&'을 먼저 연산해 버린다.

✅ 이처럼 하나의 식에서 '&&'와 '||'가 같이 사용된 경우는 괄호를 사용해주어 우선순위를 명확하게 해주는 것이 좋다.


💥 효율적인 연산(short circuit evaluation)

논리 연산자의 특징 중 효율적인 연산을 할 수 있는 것에 대해서도 나와있다.

 

OR연산의 경우, 두 피연산자 중 어느 한 쪽만 '참'이어도 전체 결과가 '참'이므로 좌측 피연산자가 'true(참)'이면, 우측 피 연산자의 값은 평가하지 않는다.

AND연산의 경우도 마찬가지로 한쪽만 '거짓(false)이어도 전체 연산결과가 '거짓'이므로 좌측 피연산자가 '거짓'이면, 우측 피연산자는 평가하지 않는다.

 

그래서 같은 조건식이라도 피연산자의 위치에 따라서 연산속도가 달라질 수 있는 것이다. 

예를 들어, OR연산 '||'의 경우에는 연산결과가 '참'일 확률이 높은 피연산자를 연산자의 왼쪽에 놓아야 더 빠른 결과를 얻을 수 있다.


2️⃣ 논리 부정 연산자 '!'

이 연산자는 피연산자가 true이면 false를, false이면 true를 결과로 반환한다. 간단하게 말해서, true와 false를 반대로 바꾸는 것이다. 연산결과를 표로 나타내면,

x !x
true false
false true

어떤 값에 논리 부정 연산자 '!'를 계속 적용하게 되면, 참과 거짓이 차례대로 반복이 된다.

이 연산자와 같은 성질을 이용하면 한번 누를 때 켜지고 다시 한번 누르는 TV의 전원버튼과 같은 '토글 버튼(toggle button)'을 논리적으로 구현할 수 있다.


3️⃣ 조건 연산자 ? :

조건식, 식1, 식2 모두 세 개의 피연산자를 필요로 하는 삼항 연산자이며, 삼항 연산자는 조건 연산자 하나뿐이다.

구조는 다음과 같이 되어 있다.

조건 연산자의 구조

그림출처 : https://thebook.io/006989/ch04/07/

가독성을 높이기 위해 조건식을 괄호()로 둘러싸는 경우가 많지만 필수는 아니다.

조건 연산자는 조건문인 if문으로 바꿔 쓸 수 있으며, if문 대신 조건 연산자를 사용하면 코드를 보다 간단히 할 수 있다.

아래의 조건 연산자가 쓰인 문장을 

result = (x > y) ? x : y;

if문으로 바꾸면 다음의 아래와 같다.

if (x > y)
	result = x; // x > y가 true일 때
else 
	result = y; // x > y가 false일 때

특징을 살펴보면 else if와 같이 결과가 증가하게 되면 조건 연산자를 쓸 수 없다.

또한, 조건 연산자를 여러 번 중첩하면 코드가 간략해지지만 가독성이 떨어지므로 꼭 필요한 경우에 한번 정도만 중첩하는 것이 좋다.


4️⃣ 대입 연산자 =, op=

변수와 같은 저장공간에 값 또는 수식의 연산결과를 저장하는데 사용된다.

이 연산자는 오른쪽 피연산자의 값을 왼쪽 피연산자에 저장한다. 그리고 저장된 값을 연산결과로 출력한다. 다음 아래와 같이 사용할 수 있다.

System.out.println(x = 3);
System.out.println(3); //위에서는 변수에 3이 저장되고 연산결과인 3이 출력된다.

대입 연산자는 연산자들 중에서 가장 낮은 우선순위를 가지고 있기 때문에 식에서 제일 나중에 수행된다. 그리고 연산 진행방향이 오른쪽에서 왼쪽이기 때문에 아래의 코드는

x = y = 3;

'y = 3' 그 다음에 ' x = y'가 수행된다.

 

✅ lvalue와 rvalue

대입연산자의 왼쪽 피연산자를 'lvaue(left value)'라고 하고, 오른쪽 피연산자를 'rvalue(right value)'라고 한다.

대입연산자의 rvalue는 변수뿐만 아니라 식이나 상수 등이 모두 가능한 반면, lvalue는 반드시 변수처럼 값을 변경할 수 있는 것이어야한다.

그래서 리터럴이나 상수같이 값을 저장할 수 없는 것들은 lvalue가 될 수 없다. 예시들을 보면

int i = 0;
3 = i + 3; // error lvalue가 값을 저장할 수 있는 공간이 아님
i + 3 = i; // error lvalue의 연산결과는 리터럴(i+3 -> 0+3 -> 3)

final int MAX = 3; // 변수 앞에 키워드 final을 붙이면 상수가 된다.
MAX = 10; // error 상수(MAX)에 새로운 값을 저장할 수 없다.

잘 보아야할 것은 final을 붙이면 상수가 되므로 상수에 한 번 저장된 값은 바꿀 수 없다.

💥 복합 대입 연산자

대입 연산자는 다른 연산자(op)와 겨랍하여 'op='와 같은 방식으로 사용될 수 있다.

예를 들어 'i = i - 5'은 'i -= 5'와 같이 표현될 수 있다. 결합된 두 연산자는 반드시 공백없이 붙여서 사용한다.

출처 : https://slidesplayer.org/slide/15044439/

 

참고문헌 -

자바의 정석 3판 남궁성 지음