Java Category/Java

[JAVA] 연산자

ReBugs 2022. 12. 25.

혼자 공부하는 자바 (저자 : 신용권)의 내용을 개인적으로 정리하는 글임을 알립니다.


연산자의 종류

연산자 종류 연산자 피연산자 수 산출값 기능
산술 +, -, *, /, % 이항 숫자 사칙연산 및 나머지 계산
부호 +, - 단항 숫자 음수와 양수의 부호
문자열 + 이항 문자열 두 문자열을 연결
대입 =, +=, -=, *=, /=, %= 이항 다양 우변의 값을 좌변의 변수에 대입
증감 ++, -- 단항 숫자 1만큼 증가 / 감소
비교 ==, !=, >, <, >=, <=, instanceof 이항 boolean 값의 비교
논리 !, &, |, &&, || 단항
이항
boolean 논리 부정, 논리곱, 논리합
조건 (조건식) ? A : B 삼항 다양 조건식에 따라 A 또는 B 중 하나를 선택

연산식은 반드시 하나의 값을 산출한다. 연산자 수가 아무리 많아도 2개 이상의 값을 산출하는 연산식은 없다.

값 대신에 연산식을 사용할 수 있다.

 

부호 연산자에서 주의해야 할 점
부호 연산자의 결과가 int 타입이라는 점이다. 예를 들어 byte 타입 변수를 부호 연산하면 int 타입으로 변환된다.
byte b = 100;
byte b = -b; -> 컴파일 에러 발생, 오버 플로
int b = -b; -> 옳은 문법
package TestPakage;
public class Test {
	public static void main(String[] args) {
		int x = -100;
		int result1 = +x;
		int result2 = -x;
		System.out.println("result1=" + result1);
		System.out.println("result2=" + result2);
		
		byte b = 100;
		//byte result3 = -b;  //int를 byte에 담으려고 하므로 오버플로
		int result3 = -b; 
		System.out.println("result3=" + result3);
	}
}
/*
result1=-100
result2=100
result3=-100
*/
증감 연산자
연산식
++ 피연산자 다른 연산을 수행하기 전에 피연산자의 값을 1 증가시킴
-- 피연산자 다른 연산을 수행하기 전에 피연산자의 값을 1 감소시킴
피연산자 ++ 다른 연산을 수행한 후에 피연산자의 값을 1 증가시킴
피연산자 -- 다른 연산을 수행한 후에 피연산자의 값을 1 감소시킴
연산식에 증감 연산자만 사용된다면 증감 연산자의 위치는 상관없다
하지만 다른 연산자와 함께 사용된다면 증감 연산자의 위치에 따라 연산식의 결과가 다르게 나온다.

증감 연산자가 변수 앞에 있으면 우선 변수 값을 1증가 또는 1감소시킨 후에 다른 연산자를 처리한다.
반면 증감 연산자가 변수 뒤에 있으면 다른 연산자를 먼저 처리한 후 변수 값을 1증가 또는 1감소시킨다.
package TestPakage;
public class Test {
	public static void main(String[] args) {
		int x = 10;
		int y = 10;
		int z;
		
		System.out.println("-----------------------");
		x++;
		++x;
		System.out.println("x=" + x); // 12

		System.out.println("-----------------------");		
		y--;
		--y;
		System.out.println("y=" + y); // 8

		System.out.println("-----------------------");		
		z = x++;
		System.out.println("z=" + z); // 12
		System.out.println("x=" + x); // 13
		
		System.out.println("-----------------------");		
		z = ++x;
		System.out.println("z=" + z); // 14
		System.out.println("x=" + x); // 14
		
		System.out.println("-----------------------");				
		z = ++x + y++;
		System.out.println("z=" + z); // 15 + 8
		System.out.println("x=" + x); // 15
		System.out.println("y=" + y); // 9
	}
}
/*
-----------------------
x=12
-----------------------
y=8
-----------------------
z=12
x=13
-----------------------
z=14
x=14
-----------------------
z=23
x=15
y=9
*/​
-피연산자들이 byte, short, char 타입일 경우 모두 int 타입으로 변환된 후에 연산을 수행
-피연산자들이 모두 정수 타입이고 long 타입이 포함되어 있을 경우, 모두 long 타입으로 변환된 후 연산을 수행
-피연산자 중 실수타입이 있을 경우, 값의 범위가 큰 실수 타입으로 변환된 후 연산을 수행
잘못된 코딩 예
byte a = 1;
byte b = 1;
byte c = a + b;

올바른 코딩 예
int c = a + b;

char c1 = 'A' + 1; // 컴파일 단계에서 연산
char c2 = 'A';
//char c3 = c2 + 1; // JVM에서 연산하므로 우변이 int로 바뀌면서 오버 플로

비교 연산자에서도 연산을 수행하기 전에 피연산자의 타입을 일치시킨다
예를 들어, 'A' == 65는 'A'가 int 타입으로 변환되어 65 = 65로 비교한다.
하지만 한 가지 예외가 있는데, 0.1 == 0.1f와 같은 경우이다.
정상적이라면 0.1f가 왼쪽 피연산자와 같은 double 타입으로 변환되어 0.1 == 0.1이 되고 true가 산출되어야 하지만, 이 결과 값은 false가 산출된다.
0.1 == 0.1f -> false
그 이유는 실수의 저장 방식인 부동 소수점 방식이 0.1을 정확히 표현할 수 없기 때문이다.
0.1f는 0.1의 근사값으로 표현되기 때문에 0.1보다 큰 값이다.
논리 연산자
AND(논리곱) / && 또는 & : 피연산자 모두가 true일 경우에만 연산 결과가 true
OR(논리합) / || 또는 | :  피연산자 중 하나만 true이면 연산 결과는 true
XOR(배타적 논리합) / ^ : 피연산자가 하나는 true이고 다른 하나가 false일 경우에만 연산 결과가 true
NOT(논리 부정) / ! : 피연산자의 논리값을 바꿈
단축평가(short circuit evaluation)
&&와 &은 산출결과는 같지만 연산 과정이 조금 다르다. &&는 앞의 피연산자가 flase라면 뒤의 피연산자를 평가하지 않고 바로 false라는 산출 결과를 낸다. 그러나 &은 두 피연산자 모두를 평가해서 산출 결과를 낸다.
따라서 
&보다 &&이 더 효율적으로 동작한다.

||과 |도 마찬가지이다.
||는 앞의 피연산자가 true라면 뒤의 피연산자를 평가하지 않고 바로 true라는 산출 결과를 낸다. 그러나 |는 두 피연산자 모두 평가를 해서 산출결과를 낸다
따라서 
|보다 ||가 더 효율적으로 동작한다.

이처럼 논리 연산의 식 전체의 평가가 단축되는 것을 단축평가라고 한다. 
삼항연산자
삼항 연산자는 ? 앞의 조건식에 따라 콜론 앞뒤의 피연산자가 선택된다고 해서 조건 연산식이라고 부르기도 함
int score = 95;
char grade = (score > 90) ? 'A' : 'B';​
? 앞의 조건식이 true(score가 90 초과)이므로 grade에는 'A'가 저장
반대로 ? 앞의 조건식이 false이면 grade에는 'B'가 저장 

 

연산의 방향과 우선순위

  • 연산의 방향은 기본적으로 왼쪽에서 오른쪽이다.
  • 연산자끼리 우선 처리되는 우선순위가 있다.
  1. 단항, 이항, 삼항 연산자 순으로 우선순위를 가진다.
  2. 산술, 비교, 논리, 대입 연산자 순으로 우선순위를 가진다.
  3. 단항, 부호 대입 연산자를 제외한 모든 연산의 방향은 왼쪽에서 오른쪽이다.
  4. 복잡한 연산식에는 괄호를 사용하여 우선순위를 정할 수 있다.

 

'Java Category > Java' 카테고리의 다른 글

[JAVA] 배열(Array)  (0) 2022.12.27
[JAVA] 참조 타입과 참조 변수  (0) 2022.12.26
[JAVA] 시스템 입출력  (0) 2022.12.24
[JAVA] 타입 변환(형 변환)  (0) 2022.12.23
[JAVA] 기본 타입  (0) 2022.12.22

댓글