연산자와 피연산자
- 연산자 : 연산을 수행하는 기호
- 피연산자 : 연산자의 연산 수행 대상
연산자의 종류
종류 | 연산자 | 설명 |
산술 연산자 | + - * / % << >> | 사칙 연산과 나머지 연산 |
비교 연산자 | > < >= <= == != | 크고 작음과 같고 다름을 비교 |
논리 연산자 | && || ! & | ^ ~ | '그리고'와'또는'으로 저건을 연결 |
대입 연산자 | = | 우변의 값을 좌변에 저장 |
기타 | (type) ? : instanceof | 형변환 연산자, 삼항 연산자, instanceof연산자 |
연산자의 우선순위
하나의 식에 연산자가 둘 이상 있을때, 어떤 연산을 먼저 수행할 것인지를 자동으로 결정하는것
※ 수동으로 결정하는 방법 : 괄호를 사용
종류 | 결합규칙 | 연산자 | 우선순위 |
단항 연산자 | ◀-------------------- | ++ -- + - ~ ! (type) | 높음 |
산술 연산자 | --------------------▶ | * / % | |
--------------------▶ | + - | ||
--------------------▶ | << >> | ||
비교연산자 | --------------------▶ | < > <= >= instanceof | |
--------------------▶ | == != | ||
논리 연산자 | --------------------▶ | & | |
--------------------▶ | ^ | ||
--------------------▶ | | | ||
--------------------▶ | && | ||
--------------------▶ | || | ||
삼항 연산자 | --------------------▶ | ?: | |
대입 연산자 | ◀-------------------- | = += -= *= /= %= <<= >>= &= ^= |= | |
낮음 |
연산자의 결합규칙
우선순위가 같은 연산자가 있을때, 어떤 것을 먼저 연산할 것인가
여기서 위에 적어놓은 표의 화살표의 의미가 나온다
대부분의 연산자는 왼쪽에서 오른쪽으로 나아가고 대입과 단항만 왼쪽에서 오른쪽으로 진행된다
정리
1. 산술 > 비교 > 논리 > 대입 으로 대입이 가장 마지막이다
2. 단항(1) > 이항(2) > 삼항(3) 으로 단항 연산자의 우선순위가 이항 연산자보다 높다
3. 단항 연산자와 대입 연산자를 제외한 모든 연산의 진행방향은 왼쪽 --------------------▶ 오른쪽 이다
증감 연산자
- 증가연산자(++) : 피연산자의 값을 1 증가 시킨다
- 전위형 : 값이 참조되기 전에 증가시킨다 ( j = ++i)
- 후위형 : 값이 참조 된 후에 증가시킨다 (j = i++)
- 감소 연산자(--) : 피연산자의 값을 1 감소 시킨다
- 전위형 : 값이 참조되기 전에 감소시킨다 (j = --i)
- 후위형 : 값이 참조 된 후에 감소시킨다 (j = i--)
- 증감 연산자가 독립적으로 사용된다면 전위형과 후위형의 차이가 없다.
부호 연산자
- - 는 피연산자의 부호를 반대로 변경
- + 는 아무런 능력이 없다
형변환 연산자
변수 또는 상수의 타입을 다른 타입으로 변화하는 것
- 방법은 간단하다 = (타입) 피연산자
double d = 85.4
int score = (int)d;
int score = (int)85.4;
int score = 85;
글만 보면 간단하지만 여기서 주의해야 할 점은 d는 여전히 85.4라는 것이다
--------------------------------------------------------------------
또
우리가 전에 큰 타입은 작은 타입으로 저장될 수 없다고 얘기했었다
하지만 여기서 우리가 형변환을 해준다면
int i = 3.14f ; 이것은 에러가 나는 코드이다
int i = (int)3.14f; 하지만 이것은 형변환이 되는 코드가 되므로 에러를 내보내지 않는다
이처럼 우리가 수동 형변환을 해준다면 가능하다는 것이다
하지만 걱정해야 할 것은 값손실이다.
3.14라는 수를 넣고 싶었지만 int형인 i에는 3만 들어가게 될 것이고 우리는 0.14라는 값이 손실됐다
이런식으로 값손실을 우려하여 수동형변환을 해준다면 더 작은 타입일지라도 저장은 오류없이 가능하다
자동 형변환
기존의 값을 최대한 보존할 수 있는 타입으로 자동 형변환된다.
float f = 1234 는서로의 타입이 불일치하지만 int타입의 값을 float 타입의 변수에 저장은 할 수 있다
하지만 원칙적으로 서로의 타입은 일치해야 한다. 그렇다면 어떻게 대입 할 수 있는것일까 그것은 자동 형변환에 있다
사실 컴파일러가 자동으로 float f = (float)1234 처럼 적어서 형변환을 해주는것이다.
사칙 연산자( + , - , / , * )
사칙연산자또한 타입이 중요하다
10 / 4 = 2 로써 int와 int로 나눈 값은 2.5이지만 이는 float형 이기때문에 2만 나오게 된다
10 / 4.0f = 10.0f / 4.0f = 2.5f 이와 같이 타입을 변경을 해주어야 우리가 원하는 값인 2.5가 나오는 것이다.
산술 변환
연산 전에 피연산자의 타입을 일치 시키는것
- 두 피연산자의 타입을 같게 일치시킨다. ( 그중 가장 큰 타입으로 일치 시킨다 )
- 피연산자의 타입이 int보다 작은 타입이면 int로 변환된다
byte + short = int + int = int
char + short = int + int = int
범위가 굉장히 좁은 int밑의 타입들은 쉽게 오버플로우가 발생할수 있다
그래서 쉽게 나오지않지만 가장 가까운 타입 int로 바뀌는 것이다
- 저번에 설명했던것 중에 문자를 숫자 타입으로 바꾸는 방법중에 '3' - '0' 이 3이 되는것을 알수 있었다
이것이 char - char = int - int 이렇게 된다는 것인데 char를 int로 바꾸는 기준은 유니코드가 된다
즉, 3의 유니코드 51, 0의 유니코드 48이 되면서 51-48 = 3이 나오게되는것이다
- 저번에 설명했던것 중에 문자를 숫자 타입으로 바꾸는 방법중에 '3' - '0' 이 3이 되는것을 알수 있었다
public static void main(String args[]) {
int a = 1_000_000;
int b = 2_000_000;
long c = a * b; // a * b 는 10의 12제곱이고 a와 b는 모두 10의 9제곱이 최대치인 int형이다
그래서 c를 출력한다면 오버플로우가 발생한다 여기서 타입을 바꿔주는것이 필요하다
long c = (long)a * b 로 한다면 문제없이 결과가 나올것이다
System.out.pringln(c);
}
반올림( Math.round() )
실수를 소수점 첫 째자리에서 반올림한 정수를 반환
long result = Math.round(4.52); 를 하면 result에는 5가 저장된다
그렇다면 원하는 자리에서 반올림하려면 어떻게 해야할까?
public static void main(String[] args) {
double pi = 3.141592;
double shortPi = Math.round(pi * 1000) / 1000.0;
System.out.println(shortPi);
}
Math.round(pi * 1000) / 1000.0
Math.round(3.141592 * 1000) / 1000.0
Math.round(3141.592) / 1000.0
(int)3142 / (double)1000.0
(double)3.142 가 되면서 Math.round로 우리가 원하는 자릿수 까지의 반올림을 사용할수 있다.
나머지 연산자 ( % )
오른쪽 피연산자로 나누고 남은 나머지를 반환
나누는 피연산자는 0이 아닌 정수만 허용(부호는 무시된다)
System.out.println(10 % 8) = 나머지 2가 출력된다
비교 연산자( > < >= <= == != )
두 피연산자를 비교해서 true(참) 또는 false(거짓)을 반환한다
비교연산자 | 연산결과 |
> | 좌변 값이 크면 true, 아니면 false |
< | 좌변 값이 작으면 true, 아니면 false |
>= | 좌변 값이 크거나 같으면 true, 아니면 false |
<= | 좌변 값이 작거나 같으면 true, 아니면 false |
== | 두 값이 같으면 true, 아니면 false |
!= | 두 값이 다르면 true, 아니면 false |
문자열 비교
문자열을 비교 할때는 == 대신 equals() 를 사용해야한다.
String str1 = "abc"
String str2 = "abc"
System.out.println(str1 == str2); // true
System.out.pringln(str1.equals(str2)); // true
String str1 = new String("abc")
String str2 = new String("abc")
System.out.println(str1 == str2); // false
System.out.pringln(str1.equals(str2)); // true
이건 나중에 중요한 내용이 되니까 이렇다 라는것을 알아두면 된다
논리 연산자 ( && | | )
조건식을 연결할 때 사용하는 연산자
- || (OR결합) : 피연산자 중 어느 한 쪽이 true이면 true 결과를 얻는다
- && (AND결합) : 피연산자 양쪽 모두 true이여야 true를 결과로 얻는다
논리 부정 연산자 ( ! )
true를 false로, false는 true로 바꾸는 것이다
boolean b = true;
!!b ▶ ! !true ▶ !false ▶ true
이런식으로 바뀐다 대입연산자는 오른쪽에서 왼쪽으로 읽어나가기 때문에 느낌표를 안쪽에서 부터 읽어준다는 예이다.
조건 연산자 ( ? : )
조건식의 결과에 따라 연산 결과를 달리 한다
- result = (x > y) ? x : y ;
- x > y 가 true라면 x 를
- x > y 가 false라면 y 를 나타내는 것이다
지금은 배우지 않았지만 앞서 보여준 3항 연산자는 if문을 간단하게 작성한것이라고 볼수 있다
result = ( x > y ) ? x : y
if ( x > y )
result = x;
else
result = y;
이와 같은 식이라고 생각하면 된다
대입 연산자
오른쪽 피연산자를 왼쪽 피연산자에 저장 후 저장된 값을 반환한다.
- lvalue : 대입 연산자의 왼쪽 피연산자 ( 저장공간- 배열, 변수 등)
- rvalue : 대입 연산자의 오른쪽 피연산자
즉, lvalue의 위치에 저장공간이 아닌 상수를 적어놓으면 오류가 난다
복합 대입 연산자
i += 3 은 i = i + 3;이라는 것과 같다 이것을 기억해서 다른 연산자도 똑같이 생각하면 된다.
※주의점이 있는데 i = i * (10 + j); 를 바꿔줄때는 i *= (10 + j) 식으로 꼭 괄호를 넣어주어야한다
'Java' 카테고리의 다른 글
캐시와 캐싱 그리고 전략. (0) | 2024.05.27 |
---|---|
Comparable 과 Comparator의 이해 (2) | 2023.10.17 |
출력 (0) | 2023.04.25 |
변수 (4) | 2023.04.24 |
Java의 기초 (0) | 2023.04.24 |