1. 연산자(operator)
1.1 연산자와 피연산자
연산자(operator) 연산을 수행하는 기호(+, -, *, / 등)
피연산자(operand) 연산자의 작업 대상(변수, 상수, 리터럴, 수식)
1.3 연산자의 종류
# 연산자의 기능별 분류
종류 | 연산자 | 설명 |
산술연산자 | + - * / % << >> | 사칙연산(+, -, *, /)과 나머지 연산(%) |
비교연산자 | > < >= <= == != | 크고 작음과 같고 다름을 비교 |
논리연산자 | && || ! | '그리고(AND)와 "또는(OR)'으로 조건을 연결 |
비트연산자 | & | ^ ~ | 피연산자를 비트단위로 논리 연산 |
대입연산자 | = | 우변의 값을 좌변에 저장 |
기타 | (type) ?: instanceof | 형변환 연산자, 삼항 연산자, instanceof 연산자 |
# 피연산자의 개수에 의한 분류
ex)
-3-5
- 첫 번째 -는 부호 연산자, 단항 연산자
- 두 번째 -는 뺄셈 연산자, 이항 연산자
1.4 연산자의 우선순위와 결합규칙
가장 높은 것 ()
가장 낮은 것 =
# 연산자 우선순위의 예시와 설명 (><로 우선순위 여부 표시)
- 단항 연산자 > 이항 연산자
ex) -x + 3
- 곱셈/나눗셈 > 덧셈/뺄셈
ex) x + 3 * y
- 산술연산자(+, -) > 비교연산자(>)
ex) x + 3 > y - 2
- 비교연산자 > 논리연산자 &&
ex) x > 3 && x < 5
- 대입연산자는 우선순위가 가장 낮다
ex) result = x + y * 3;
- 덧셈연산자 > shift연산자(<<)
ex) x << 2 + 1
- 비교연산자(==) > 비트연산자(&)
ex) data & 0xFF == 0 (문법적에러 발생되는 예시임 - true, false로는 비트연산이 불가하기 때문!)
- AND(&, &&) > OR(|, ||)
ex) x < -1 || x > 3 && x < 5
# 연산자의 결합규칙
연산자마다 다르지만, 대부분 왼쪽 → 오른쪽 순으로 연산을 수행하고,
단항연산자와 대입연산자만 오른쪽 → 왼쪽 순으로 연산을 수행한다.
- 연산자의 우선순위와 결합규칙 정리 표
종류 | 결합규칙 | 연산자 | 우선순위 |
단항연산자 | ← | ++ -- + - ~ ! (type) | 높음 낮음 |
산술연산자 | → | * / % | |
→ | + - | ||
→ | << >> | ||
비교연산자 | → | < > <= >= instanceof | |
→ | == != | ||
논리연산자 | → | & | |
→ | ^ | ||
→ | | | ||
→ | && | ||
→ | || | ||
삼항연산자 | → | ?: | |
대입연산자 | ← | = += -= *= /= %= <<= >>= &= ^= |= |
1.5 산술변환(usual arithmetic conversion)
연산 수행 직전에 발생하는 피연산자의 자동 형변환
- 산술변환 규칙
① 두 피연산자의 타입을 같게 일치시킨다(보다 큰 타입으로 일치)
long + int → long + long → long
float + int → float + float → float
double + float → double + double → double
② 피연산자의 타입이 int보다 작은 타입이면 int로 변환된다.
byte + short → int + int → int
char + short → int + int → int
2. 단항연산자
2.1 증감연산자(++, --)
피연산자에 저장된 값을 1 증가 또는 1 감소시킨다.
- 전위형과 후위형의 비교
타입 | 설명 | 예시 |
전위형 | 값이 참조되기 전에 증가시킨다. | j = ++i; → ++i; // 증가 후 j = i; 참조하여 대입 |
후위형 | 값이 참조된 후에 증가시킨다. | j = i++; → j = i; // 참조하여 대입 후 ㅑ++; 증가 |
2.2 부호연산자(+, -)
피연산자의 부호를 반대로 변경한 결과를 반환한다.
피연산자가 음수면 양수, 양수면 음수가 연산 결과가 된다.
3. 산술연산자
3.1 사칙연산자(+, -, *, /)
- 정수형은 나눈 결과에서 소수점 이하는 버려진다.
ex) int 10 / int 4 → int 2
- 크기가 작은 자료형의 변수를 큰 자료형의 변수에 저장할 때는 자동형변환 되지만,
반대로 크기가 큰 자료형의 값을 작은 자료형의 변수에 저장하려면
명시적으로 형변환 연산자를 사용해서 변환해주어야 한다.
# 숫자와 영문자의 유니코드표
문자 | 코드 | 문자 | 코드 | 문자 | 코드 |
0 | 48 | A | 65 | a | 97 |
1 | 49 | B | 66 | b | 98 |
2 | 50 | C | 67 | c | 99 |
3 | 51 | D | 68 | d | 100 |
4 | 52 | E | 69 | e | 101 |
5 | 53 | ... | ... | ... | ... |
.. | .. | X | 88 | x | 120 |
8 | 56 | Y | 89 | y | 121 |
9 | 57 | Z | 90 | z | 122 |
// Tip : 유니코드를 모를 땐
ex) char ch = 'A';
System.out.print((int)ch); 를 작성해 확인해보기!
- 리터럴, 상수 간의 연산은 형변환 해주지 않아도
실행과정동안 변하는 값이 아니기 때문에 컴파일 시 컴파일러가 계산하여 그 결과로 대체한다.
이로 인해, 코드를 보다 효율적으로 만들어준다.
반대로 코드의 가독성과 유지보수를 위해서 일부러 뻔한 리터럴 연산을 풀어쓰는 경우도 있다.
풀어쓰더라도 컴파일러에 의해 미리 계산되기 때문에 실행 시 성능차이는 없다.
ex)
컴파일 전의 코드 | 컴파일 후의 코드 |
char c2 = 'a'+1; int sec = 60 * 60 *24; |
char c2 = 'b'; int sec = 86400; |
↕
char c2 = c1 + 1; → char c2 = (char)(c1+1); // 변수 간의 연산
# 버림 / 반올림
- 버림
ex)
class OperatorEx16{
public static void main(String[] args) {
float pi = 3.141592f;
float shortPi = (int)(pi*1000) / 1000f;
System.out.println(shortPi); // 결과 : 3.141
}
}
int형 간의 나눔셈을 수행하면 결과는 int가 된다.(float나 double 아님 주의)
또한 나눗셈의 결과를 반올림 하는 것이 아니라 버림한다.
- 반올림
ex)
class OperatorEx17{
public static void main(String[] args) {
double pi = 3.141592f;
double shortPi = (int)(pi * 1000 + 0.5) / 1000.0;
System.out.println(shortPi); // 결과 : 3.142
}
}
반올림을 위해 0.5를 더해줌
- Math.round() : 매개변수로 받은 값을 소수점 첫째자리에서 반올림 하고 그 결과를 정수로 돌려주는 메소드
위의 반올림 방법보다 더 간단히 처리할 수 있다.
ex)
class OperatorEx18{
public static void main(String[] args) {
double pi = 3.141592;
double shortPi = Math.round(pi * 1000) / 1000.0;
System.out.println(shortPi); // 결과 : 3.142
}
}
★ Math.round() : 반올림
Math.ceil() : 올림 (천장)
Math.floor() : 내림 (바닥)
위의 세 가지 메소드들은 무조건 소수점 이하가 있는 경우 해당 메소드를 실행한다.
실제 코딩 시 많이 사용하므로 암기해두자!
Q. 사용자로 부터 문자하나를 입력받아,
입력받은 값이 숫자이면, '숫자', 소문자이면, '소문자', 대문자이면 '대문자'라고 출력하자. (자바의 정석 p.117)
Scanner scanner = new Scanner(System.in);
char ch = ' ';
System.out.println("문자를 하나 입력하세요.>");
String input = scanner.nextLine();
ch = input.charAt(0)
A.
import java.util.Scanner;
public class Operator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
char ch = ' ';
System.out.println("문자를 하나 입력하세요.>");
while(true) {
String input = scanner.nextLine();
ch = input.charAt(0);
if(input.length() == 1) {
scanner.close();
break;
}
else {
System.out.println("한 글자만 입력해주세요.");
System.out.println("다시 입력해주세요.");
}
}
if('0' <= ch && ch <= '9')
System.out.println("숫자");
else if('a'<= ch && ch <='z')
System.out.println("소문자");
else if ('A'<=ch && ch <='Z')
System.out.println("대문자");
scanner.close();
}
}
3.2 나머지 연산자 (%)
왼쪽의 피연산자를 오른쪽 피연산자로 나누고 난 나머지 값을 결과로 반환하는 연산자
나누는 수로 음수도 허용한다.
따라서 피연산자의 부호를 모두 무시하고,
나머지 연산을 한 결과에 왼쪽 피연산자(나눠지는 수)의 부호를 붙이면 된다.
4. 비교 연산자
4.2 등가비교 연산자( ==, !=)
- == : 두 값이 같으면 true, 아니면 false
- != : 두 값이 다르면 true, 아니면 false
// Tip : >=와 같이 두 개의 기호로 이루어진 연산자는
기호의 순서 바꾸는 것과 중간에 공백이 있는 것을 허용하지 않는다.
ex) 10.0 = 10.0f의 결과는 false인데
이는 정수형과 달리 실수형은 근사값으로 저장되므로 오차가 발생할 수 있기 때문이다.
# 문자열의 비교 (equals())
equals 메소드는 비교하고자 하는 대상의 내용 자체를 비교
== 연산자는 비교하고자 하는 대상의 주소값을 비교
5. 논리연산자
5.1 논리연산자( &&, ||, !)
- || (OR 결합) : 피연산자 중 어느 한 쪽만 true이면 true를 결과로 얻는다.
- && (AND 결합) : 피연산자 양쪽 모두 true여야 true를 결과로 얻는다.
# 효율적인 연산 - Short Circuit Evaluation(SCE, 숏 서킷 연산 : 연산생략)
AND 혹은 OR 의 연산에 있어서 결과가 확실하게 예측이 되었을 때
뒤에 나머지 연산을 실행하지 않고 답을 내버리는 경우를 의미
# 논리 부정 연산자(!)
!true = false
5.2 비트연산자( &, |, ^, ~, <<, >> )
- | (OR연산자) : 피연산자 중 한 쪽의 값이 1이면, 1을 결과로 얻는다. 그 외에는 0을 얻는다.
- & (AND연산자) : 피연산자 양 쪽이 모두 1이어야만 1을 결과로 얻는다. 그 외에는 0을 얻는다.
- ^ (XOR연산자) : 피연산자의 값이 서로 다를 때만 1을 결과로 얻는다. 같을 때는 0을 얻는다.
Q. 사용자로 부터 int형 정수하나를 입력받아, 그 값을 4byte 이진수 형태로 출력하자. (자바의 정석 p.122)
ex)
10진 정수를 입력하세요.
10
2진수
00000000000000000000000000001010
[참고] Integer.toBinaryString(10); 를 이용해보시오.
A. 교재 답
class OperatorEx28{
public static void main(String[] args) {
int x = 0xAB, y = 0xF;
System.out.printf("x = %#X \t\t%s%n", x, toBinaryString(x));
System.out.printf("y = %#X \t\t%s%n", y, toBinaryString(y));
System.out.printf("%#X | %#X = %#X \t%s%n", x, y, x | y, toBinaryString(x | y));
System.out.printf("%#X & %#X = %#X \t%s%n", x, y, x & y, toBinaryString(x & y));
System.out.printf("%#X ^ %#X = %#X \t%s%n", x, y, x ^ y, toBinaryString(x ^ y));
System.out.printf("%#X ^ %#X ^ %#X = %#X \t%s%n", x, y, y, x ^ y ^ y, toBinaryString(x ^ y ^ y));
}
static String toBinaryString(int x) {
String zero = "00000000000000000000000000000000";
String tmp = zero + Integer.toBinaryString(x);
return tmp.substring(tmp.length()-32);
}
}
A. 내가 생각한 답
package practice0727;
import java.util.Scanner;
public class Operator2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("10진 정수를 하나 입력하세요.>");
int input = scanner.nextInt();
String temp = "";
String binary = Integer.toBinaryString(input);
for (int i = 0; i < 32-binary.length(); i++) {
temp += 0;
}
temp = temp+binary;
System.out.println("2진수 :"+temp);
scanner.close();
}
}
# 비트 전환 연산자 (~)
피연산자를 2진수로 표현했을 때, 0은 1로 1은 0으로 바꾼다.
논리부정 연산자(!)와 유사하다.
# 쉬프트연산자(<<, >>)
피연산자의 각 자리(2진수로 표현했을 때)를 '오른쪽(>>)' 또는 '왼쪽(<<)'으로 이동(shift)한다.
ex) 8<<2 : 왼쪽 피연산자인 10진수 8의 2진수를 왼쪽으로 2자리 이동한다.
빈칸은 0으로 채운다.
8>>2 : 10진수 8의 2진수를 오른쪽으로 2자리 이동한다.
빈칸은 음수인 경우 1, 양수는 0으로 채운다.
6. 그 외의 연산자
6.1 조건연산자 ?: (= 삼항연산자)
자바 내 유일한 삼항연산자이다.
조건식? 식1 : 식2
(참) (거짓)
ex) absX = x >=0? x : -x;
6.2 대입연산자 (=, op=)
변수와 같은 저장공간에 값 또는 수식의 연산결과를 저장하는데 사용
# 복합대입연산자
'SW > Java' 카테고리의 다른 글
[필기정리] Day61 - 2진검색 예제문제 (0) | 2020.09.17 |
---|---|
[용어정리] 선택정렬(Selection Sort), 버블정렬(Bubble Sort) (0) | 2020.09.11 |
[개념정리] Java의 정석 Chapter 2 변수 (0) | 2020.07.24 |
[개념정리] Java의 정석 Chapter 1 자바를 시작하기 전에 (0) | 2020.07.24 |
[문제] 자바의 정석 Chapter 7 객체지향 프로그래밍 2 연습문제 및 해답정리 (0) | 2020.07.24 |