Java의 정석(3) - 연산자(operator)

김주혁's avatar
May 30, 2024
Java의 정석(3) - 연산자(operator)
 
 

 

자바의 정석(standardOfJava) 2024.05.01 ~

1. 연산자(operator)

 

1.1 연산자와 피 연산자

연산자가 연산을 하려면 반드시 연산의 대상이 필요한데, 이를 피 연산자라고 한다.
x + 3 + => 연산자 x , 3 => 피 연산자
 

1.2 식(式)과 연산자

연산자와 피 연산자를 조합하여 계산하고자 하는 결과를 표현한 것을 식이라고 한다.
 

1.3 연산자의 종류

  • 산술 연산자
    • +, -, *, /, %, <<, >>
  • 비교 연산자
    • >, <, >=, <=, ==, !=
  • 논리 연산자
    • &&, ||, !, &, |, ^, ~
  • 대입 연산자
    • =
  • 기타
    • (type) > type casting 형변환 연산자 ? : > 삼항 연산자 instanceof 클래스 인스턴스 연산자
 

1.4 연산자의 우선순위와 결합규칙

연산자가 둘 이상인 경우, 우선순위에 의해 결정된다.
사칙연산의 우선순위는 제외하고,
 
  • 산술 연산자 > 비교 연산자 > 논리 연산자 > 대입 연산자 순으로 동작한다.
  • && , & > ||, |
  • 비트 연산자 &는 비교 연산자(==)보다 우선순위가 낮다.
 
대부분의 연산자는 왼쪽에서 오른쪽으로 연산을 수행한다.
 
다만, 단항연산자만 그 반대로 오른쪽에서 왼쪽으로 연산을 수행한다.
3 + 4 - 5 => 왼쪽에서 오른쪽 x = y = 3 => 오른쪽에서 왼쪽
대입 연산자는 우변의 값을 좌변에 저장한다.
 
정리하면 다음과 같다.
  • 산술 > 비교 > 논리 > 대입
  • 단항(1) > 이항(2) > 삼항(3)
  • 단항 연산자와 대입 연산자를 제외한 모든 연산의 진행방향은 왼쪽에서 오른쪽이다.
 

1.5 산술 변환

이항 연산자는 두 피연산자의 타입이 일치해야 연산이 가능하기 때문에, 타입이 서로 다를 경우 연산 전 형변환을 시켜줘야 한다. 대부분의 경우 두 연산자 중, 더 큰 타입으로 일치시킨다.
 
큰 타입으로 형 변환 시, 형변환연산자 생략 가능하다.
long + int => long float + int => float double + float => double byte + short => int
 
하지만 여기서 주의해야 할 점은, 연산결과의 타입이다. 예를들면,
int / int => int 다. 5 / 2 => 2.5 x 2 o 이게 뭐가 문제인가? => 소수점 이하는 버려진다.

2. 단항 연산자

 

2.1 증감 연산자 ( ++, —)

증감연산자는 피연산자에 저장된 값을 1 증가 또는 감소시킨다. 상수를 변경시킬 수는 없다. 왼쪽에 위치한 증감 연산자를 전위형, 오른쪽에 위치한 증감 연산자를 후위형이라고 한다.
 
전위형과 후위형에 따라 동작이 다른데, 전위형은 ++v 값이 참조되기 전에 증가시킨다. 후위형은 값이 참조된 후에 증가시킨다.
 
다만, 수식이나 메서드 호출에 포함되지 않고 독립적으로 사용된다면 차이가 없다.
 

2.2 부호 연산자 ( +, -)

부호 연산자는 부호를 반대로 변경한 결과를 반환한다.
int i = -10; i = +i; // -10 int i = -10; i = -i; // 10

3. 산술 연산자

 

3.1 사칙 연산자 ( +, -, *, / )

사칙연산에 사용된다.
 
피연산자가 정수형인 경우, 나누는 수로 0을 사용할 수 없다.
 
만약, 10과 4를 a, b에 저장하여 사칙연산을 수행하고 결과를 출력한다면
(int) 10 / (int) 4 => (int) 2 // 2.5가 아님 소수점 이하는 버려진다.
int와 int를 나누면 결과 값도 int가 된다.
 
int는 정수만을 저장하기 때문에 소수점 이하는 버려지고, 반올림이 발생하지 않는다. 여기서 하고 싶은 말은 java는 강 타입 언어라는 것이다.
 
만약 올바른 연산결과를 얻고 싶다면 어느 한 쪽을 실수형으로 바꿔야 한다.
(int) 10 / (float) 4.0f => 2.5f
 
보통 자바는 큰 타입으로 일치시킨다는 점을 항상 명심하자.
 
만약 피 연산자가 정수형일 때 0 으로 나누면 에러가 발생하지만 부동 소수점값인 0.0f나 0.0d로 나누면 Infinity값이 출력된다.
 
x
y
x/y
x % y
유한수
+- 0.0
+-Infinity
NAN
유한수
+-Infinity
+- 0.0
x
+- 0.0
+-0.0
NaN
NaN
+-Infinity
유한수
+-Infinity
NaN
+-Infinity
+-Infinity
NaN
NaN
계속 강조되는 얘기지만, 사칙연산의 결과가 타입과 맞지 않으면 값의 손실이 발생할 수 있다.
 
언제나 충분히 큰 타입을 사용하는 것이 좋다.
int 1_000_000 * int 1_000_000 = -727379968 // 10^12 가 아니다.
 
사칙연산으로 숫자뿐만 아니라 문자도 가능하다.
 
숫자와 영문의 유니코드를 통해
'd' - 'a' -> 100 - 97 -> 3 'a' + 1 -> 97 + 1 -> 98 char b = 'a' + 1( 97 + 1 )
와 같은 연산도 가능하다.
 

3.2 나머지 연산자 %

나머지 연산자는 좌항을 우항으로 나눈 나머지 값을 결과값으로 반환한다.
 

4. 비교 연산자

 

4.1 대소비교 연산자 ( >, <, ≥, ≤ )

참이면 true, 거짓이면 false를 반환한다. 참조형에는 사용할 수 없다.
 

4.2 등가비교 연산자 ( ==, ≠)

값이 같은지 다른지를 비교한다. 모든 자료형에 사용할 수 있다. 비교 연산자도 이항 연산자기 때문에 비교 전 서로의 타입을 일치시킨 후 비교한다. 한 가지 주의할 점은
10.0 = 10.0f => true 0.1 => 0.1f => false
라는 점인데, 소수점은 근사 값의 오차가 발생할 수 있기 때문이다.
 
0.1f는 저장할 때 2진수로 바꾸는 과정에서 오차가 발생한다.
float f = 0.1f; // 0.1000000000149011612 double d = 0.1f; // 0.100000000000000001
 
만약 float과 double 타입을 비교하려면, double타입의 값을 float으로 변경 후 비교해야 한다.
 
문자열의 비교에는 ==, ≠ 보다는 equals를 사용해야 한다.
 
String str1 = "abc"; String str2 = new String("abc") "abc" == "abc" ? true str2 == "abc" ? false str2.equals("abc") ? true
 
str2와 “abc”가 다른 이유는 같이 같은데도, 서로 다른 객체라서 그렇다. equals를 사용하면 true인데 이래서 equals를 사용해야 한다.
 

5. 논리 연산자

 

5.1 논리 연산자 ( &&, ||, ! )

 
  • && → and
  • || → or
논리 부정 연산자 !는 피연산자가 true면 false를, false면 true를 결과로 반환한다.
 

5.2 비트 연산자 ( &, |, ^, ~, <<, >> )

 
  • | (OR), 피연산자 중 한 쪽 값이 1이면 1을 결과로
  • & (AND), 양쪽 다 1이여야안 1을 결과로
  • ^ (XOR), 피연산자의 값이 서로 다를 때만 1
  • ~ (비트 전환 연산자), x = 1일 때 ~x는 0
양의 정 수 p가 있을 때 음의 정수를 얻으려면 ~p+1을 하면 된다.
 
  • <<, >> 쉬프트 연산자
    •  
      피 연산자의 각 자리(2진수로 표현한 경우)를 오른쪽 또는 왼쪽으로 이동시킨다.
      8<<2는 왼쪽 피연산자인 10진수 8의 2진수를 왼쪽 2자리로 이동한다.
      수식
      10진수
      8 >> 0
      8
      8 >> 1
      4
      -8 >> 0
      -8
      -8 >> 2
      -4
      귀찮게 쉬프트 연산자를 사용하는 이유는 무엇일 까?
       
      그 이유는 빠르기 때문이다.
       

6. 그 외의 연산자

 

6.1 조건 연산자 ? :

삼항연산자를 의미한다.
 
삼항 연산자를 남발하면 가독성이 떨어지기 때문에 간단한 문장에만 사용하자!
 

6.2 대입 연산자 =, op=

~는 이다. 값을 저장할 때나 연산결과를 저장할 때 사용한다.
 
대입 연산자는 연산 순위에서 가장 낮기 때문에 가장 마지막으로 수행된다.
 
좌항에는 항상 변수처럼 값을 저장할 수 있는 것이여야한다.
 
  • 복합 대입 연산자
    •  
      op=
      =
      i +=3;
      i + 3;
      i -= 3;
      i - 3;
      ..
      ..
Share article

vlogue