본문 바로가기
백엔드/Java

[Java] 3. 주의해야할 연산자 특징들

by BGwon_C 2023. 7. 31.

연산자의 우선순위

1. 산술 > 비교 > 논리 > 대입
    대입은 제일 마지막에 수행된다.

2. 단항(1) > 이항(2) > 삼항(3)
    단항 연산자의 우선순위가 이항 연산자보다 높다.

3. 단항 연산자와 대입 연산자를 제외한 모든 연산의 진행방향은 왼쪽에서 오른쪽이다.

 

부호 연산자 (+, -)

1. 부호 연산자 '+'는 하는 일이 없으며 '-'가 있으니까 형식적으로 추가해놓은 것 뿐이다.

2. 부호 연산자 '-'는 피연산자가 음수면 양수, 양수면 음수로 변경한다.

부호 연산자는 boolean형과 char을 제외한 기본형에서만 사용할 수 있다.

형변환(casting) 연산자

형변환이란 변수 또는 상수의 타입을 다른 타입으로 변환하는 것을 말한다.

형변환하고자 하는 변수나 리터럴의 앞에 원하는 타입을 괄호로 적어주면 되는데, 여기서 사용되는 괄호()는 '캐스트(형변환) 연산자'라고 하며, 형변환을 '캐스팅(casting)' 이라고도 한다.

참고로 형변환의 결과는 그 값을 대입한 피연산자 변수의 값에는 영향을 미치지 않는다. 예를들어 아래와 같은 코드에서

 

double d = 85.4;

int score = (int)d;

 

변수 score의 결과는 int형으로 형변환되어 소수점 아래가 사라진 '85'가 되지만,

변수 d의 값은 그대로 85.4가 된다.

 

※ 형변환의 다양한 예시

변환 수식 결과
int -> char (char) 65 'A'
char -> int (int) 'A' 65
float -> int (int) 1.6f 1
int -> float (float) 10 10.0f

 

자동 형변환

서로 다른 타입 간 대입이나 연산을 할 때, 형변환으로 타입을 일치시키는 것이 원칙이지만, 편의상 형변환을 생략할 수 있다. 만약 형변환을 생략하면 컴파일러가 알아서 자동적으로 형변환을 한다. (두 타입 중에서 표현범위가 더 넓은쪽으로 형변환된다.)

float f = 1234; // float  f = (float)1234;에서 (float)가 생략됨

위 문장에서 1234는 int 타입의 상수이고, 이 값을 저장하려는 변수의 타입은 float이다. 서로 타입이 다라서 형변환이 필요하지만 float타입은 int형보다 크기때문에 저장하는데 아무런 문제가 없다. 따라서 편의상 생략이 가능하다. (반대로 더 큰 상수값을 작은 타입의 변수에 담으려고 하면 반드시 형변환 표시를 해야한다.)

 

주의할 점은 자동 형변환시 변수가 저장할 수 있는 범위보다 더 큰 값을 저장하려는 경우에는 에러가 발생한다는 것이다. 

byte b = 1000; // 에러발생. byte타입의 범위를 초과함

 

그러나 다음과 같이 명시적으로 형변환을 해줬을 경우, 형변환이 프로그래머의 실수가 아닌 의도적인 것으로 간주하고 컴파일러는 에러를 발생시키지 않는다.

byte b = (byte)1000; // 정상실행. but 값 손실이 발생해서 변수 b에는 -24가 저장됨.

 

사칙 연산자 및 산술 변환

수수점 이하의 결과를 원할 떄, 올바른 연산결과를 위해서는 둘 중 한쪽을 실수형으로 형변환 해야 한다. 그래야 다른 한 쪽도 같이 실수형으로 자동 형변환되어 실수형의 값을 결과로 얻을 수 있다. 이런 식으로  연산 직전에 발생하는 자동 형변환을 산술 변환이라고 한다.

아래의 예시를 보자

int a = 5;

int b = 3;

float f = (float) a/b;   // 결과 : 1.6666666...

float f = (float) (a/b); // 결과 : 1.0

 

같은 연산인데 왜 둘의 결과가 다르게 나올까? 바로 산술 변환의 순서에 있다.

위의 코드는 먼저 a를 float로 강제 형변환한 후에 b와 나누기 연산을 수행한다. 즉, aint 타입에서 float 타입으로 형변환되므로, 55.0으로 변환된다. 그리고 5.0 / 3 연산이 수행되면 더 큰 데이터 타입에 담으므로 변수 f의 값은 1.6666666...의 부동소수점 결과를 내게 된다.

반면에 아래의 코드는 float로 형변환 하기전에 먼저 (a/b)를 수행하게 된다. 정수인 5와 3을 나누므로 결과값은 정수인 1을 반환하게 되고, 이 결과값 1을 float으로 형변환하기때문에 1.0이라는 결과를 내게 된다.

이처럼 산술 변환 수행시의 결과값은 연산 순서에 따라 달라지기 때문에 항상 유의해야 한다.

 

복합 대입 연산자

i *= 10 + j; 는 i= i * 10 + j; 가 아니라 i = i * (10 +j);이다. 주의하자

댓글