[1] 연산자와 피연산자
연산자(Operator)
: 어떤 기능을 수행하는 기호 . 연산 수행의 주체.
ex) 산술연산자 , 대입연산자 등
피연산자(Operand)
: 연산자의 작업 대상.
ex) 변수, 상수, 리터럴, 수식
[2] 연산자의 종류
연산자는 기준에 따라 다르게 분류할 수 있는데,
피연산자의 개수에 따른 분류는 아래와 같다.
1. 단항연산자 (부호, 증감, 비트전환, 논리부정)
2. 이항연산자
3. 삼항연산자(조건연산자)
1. 단항연산자
: 피연산자가 1개인 연산자.
→ 부호, 증감, 비트, 논리부정
부호 : + , -
양수, 음수를 표현하는 부호. 양수는 부호를 생략할 수 있다.
증감 연산자 : ++, --
증가 연산자 (++) : 피연산자의 값을 1 증가시킨다.
감소 연산자 (--) : 피연산자의 값을 1 감소시킨다.
증감 연산자는 전위형과 후위형으로 나뉜다.
후위형 : i++; // 값이 참조되기 전에 증가시킴
전위형 : ++i; // 값이 참조된 후 증가
int x = 10;
int y = 10;
System.out.println((x++)); // 10
System.out.println(x); // 11
System.out.println(++y); // 11
System.out.println(y); // 11
비트 (전환)연산자 : ~
비트를 뒤집는 연산자. (0을 1로, 1을 0으로)
cpu는 감산이 불가능하고 가산, 누산만 처리할 수 있다.
이 때, 피연산자를 2진수로 표현한 후 모든 수를 뒤집고 1을 더하면 부호를 바꿀 수 있다.
(1의 보수 개념을 이용한 비트 전환연산)
따라서 비트 전환 연산자를 1의 보수 연산자라고도 한다.
* 참고: 10진수를 2진수로 쉽게 바꾸는 법
2에 가능한 가장 큰 수로 곱하면서 우측에는 나머지를, 좌측은 2, 아래는 곱한 수를 작성.
나머지를 아래에서 우측 위로 순서대로 적으면 2진수가 된다.
------- ex) 5 는 2진수로 101
2 | 5 . . . 1 (나머지)
----
2 | 2 . . . 0
----
1
------ ex) 6은 2진수로 110
2 | 6 . . . 0 (나머지)
----
2 | 3 . . . 1
----
1
논리 부정 (not)연산자 : ~
boolean 값을 가지는 대상의 true/false 값을 반전시킨다.
따라서 피연산자의 자료형이 boolean일때만 사용 가능하다.
public class Operator_03 {
public static void main(String[] args) {
boolean power = false;
System.out.println("power 값: " + power);
System.out.println("power 값: " + !power);
if(power) {
System.out.println("전원이 켜져있습니다.");
}else{
System.out.println("전원이 꺼져있습니다.");
}
}
}
2.이항연산자
: 피연산자가 2개인 연산자.
이항연산자와 형 변환
이항 연산자는 연산 실행 전, 피연산자의 타입을 일치시키는 작업을 한다.
- 디폴트 타입 int보다 바이트 수가 작은 타입은 int로 자동 변환된다.
- 정수와 실수의 연산은, 표현 범위가 더 넓은 타입으로 형 변환 된다.
: byte + short => int + int => int
: char + int => int + int => int
: int + float => float + float => float
: double + float => double + double => double
public class Default_type {
public static void main(String[] args) {
// 이항 연산자와 디폴트 타입
byte b1 = 127;
byte b2 = 1;
float f1 = 15.5f;
double d1 = 10.5;
//byte b3 = b1 + b2; 오버플로우 에러
// 해결 1: int 형으로 받는다 (자동 캐스팅)
int b3 = b1 + b2; // 128
// 해결 2: 강제 캐스팅 = > 데이터 손실, 루핑
byte b4 = (byte)(b1 + b2); // -128
System.out.println(b3 + "," + b4);
// 정수와 실수 => 범위가 넓은 쪽으로 연산
float f2 = b1 + f1; // 127 + 15.5
double d2 = f1 + d1; // 15.5 + 10.5
System.out.println(f2 + ", " + d2);//142.5, 26.0
}
}
이항연산자의 종류
: 산술, 대입, 비교, 논리, 비트
- 산술 : + - * / % << >>
좌항과 우항을 산술 연산하는 연산자.
* 시프트 연산자 ( << , >> )
left shift operator, right shift operator.
2의 n 제곱 으로 곱하거나 나눈 결과를 반환한다.
속도가 빨라서 그래픽 분야에서 많이 사용.(복잡한 연산이 아니라 비트 위치만 이동하므로)
x << n 은 x * 2의 n제곱 과 같다. / 비트를 왼쪽 끝에서 n개만큼 잘라 오른쪽 끝으로 붙인다.
x >> n 은 x / 2의 n제곱 과 같다. / 비트를 오른쪽 끝에서 n개만큼 잘라 왼쪽 끝으로 붙인다.
- 대입 : =
대입과 복합대입 연산자는 유일하게 우측에서 좌측으로 실행되는 연산자.
단, 상수는 예외 (실행 불가)
- 복합대입: += -= *= /= %=
(Compound Assignment Operators)
변수가 포함된 산술 연산식을 해당 변수에 재할당하는 경우, 이를 간단하게 줄여쓰는 연산자.
값을 누적시킬 때 주로 사용된다.
sum = sum + 1
sum += 1
- 비교 : > < >= =< == !=
두 항의 크기를 비교하거나 동일 값 여부를 판단한다.
피연산자를 같은 타입으로 변환한 후, 비교 실행. ( 결과는 true 또는 false가 된다.)
ex) A < B => 65 < 66 ( int로 변환) => true.
10.0d == 10.0f => 10.0d == 10.0d (double로 변환) => true
boolean을 제외한) 기본형과 참조형에 사용되며,
참조형 변수는 == 와 != 만 사용 가능하다. 참조형은 기본적으로 주소 비교가 실행된다.
값에 대한 비교는 .equals(String) 메서드를 사용한다.
System.out.println(true == true); // true
System.out.println(true != false); // false
System.out.println(true > false);
//error: bad operand types for binary operator '>'
public class Main
{
public static void main(String[] args) {
String a = "사과";
String b = "포도";
String c = "사과";
System.out.println("a == b : " + a==b);
System.out.println("a == c : " + a==c);
System.out.println("a != b :" + a!=b);
System.out.println("a.equals("사과") : " + a.equals("사과"));
System.out.println("a.equals(c) : " + a.equals(c));
}
}
/*
false
false
true
a.equals("사과") : true
a.equals(c) : true
*/
public class Main
{
public static void main(String[] args) {
// 참조형 타입의 == , != 는 리터럴의 메모리 위치주소를 비교.
String str1 = "재미있는";
String str2 = "자바"; // 기존에 없던 리터럴이므로 새로운 곳에 인스턴스 생성.
String str3 = "자바"; // 힙에 같은 리터럴이 이미 있음. 따라서 주소를 공유.
String str4 = new String("자바"); // 새로운 인스턴스 생성.
boolean result = (str1 == str2);
System.out.println(result); //false (리터럴이 다르니 주소도 다름)
// (어? 이미 있는 값이네? 너도 여기를 pointing 해!)
boolean result2 = (str2 == str3);
System.out.println(result2); //true (주소가 같음)
boolean result3 = (str3 == str4);
System.out.println(result3); //false (같은 리터럴이지만 다른 주소에 각각 존재)
System.out.println(str1.equals(str2)); // false
System.out.println(str2.equals(str3)); // true
}
}
- 논리 : && ||
: 더블엔드 (&&) : 피연산자 둘 다 true 면 ture.
: 더블파이프: 피연산자 중 어느 한쪽이라도 true 면, true.
: 피연산자와 연산 결과 모두 반드시 boolean type 이어야 한다.
: &&가 ||보다 우선순위가 높다.
따라서 함께 사용하는 경우 가독성과 편의를 위해 괄호를 사용한다.
cf) &와 |는 비트연산자가 선점한 문법. 2개씩 써야 논리 연산자.
(i > 3) && (i < 5) //false.
(i > 3) || (i < 0) //true
// ex) x에 저장된 값이 알파벳인지 확인하는 조건
(x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z')
// 소문자 OR 대문자.
- 비트 연산자: & | ^
기호 이름: 앤드 , 파이프, 캐럿
피연산자를 비트 단위로 연산한다. 단, 실수는 제외 (정수만 계산 가능)
& (and) 연산자 : 피연산자 둘 다 1이어야 1.
| (or) 연산자 : 피연산자 중 한쪽이라도 1이면 1.
^ (xor) 연산자 : 피연산자가 서로 달라야 1. (= 배타적 논리합, exclusive or)
// & , | , ^ : 비트 연산자 ( and, or, xor )
int x = 8;
int y = 5;
System.out.println("x를 2진수로 변환하면: " + Integer.toBinaryString(x));
System.out.println("y를 2진수로 변환하면: " + Integer.toBinaryString(y));
System.out.println("x & y = " + (x & y)); // 둘 다 1일 때 1.
System.out.println("x | y = " + (x | y)); // 둘 중 하나라도 1이면 1.
System.out.println("x ^ y = " + (x ^ y)); // 서로 값이 다를 때 1
/*
x를 2진수로 변환하면: 1000
y를 2진수로 변환하면: 101
x & y = 0
x | y = 13
x ^ y = 13
*/
3. 삼항 연산자 (조건 연산자)
(조건식) ? 표현식 1 : 표현식2
: 조건식의 연산 결과가 true면, 표현식 1의 결과를 반환하고,
false인 경우 표현식2의 결과를 반환한다.
(if = else문의 대체 문법. 더 간결함)
int score = 70;
char grade = (score >= 90) ? 'A' : (score >= 80 ? 'B' : 'C');
// grade = C
[3] 연산자의 우선순위
1. 괄호가 우선 순위가 가장 높다.
2. 연산자 우선 순위 : 단항 > 이항 > 삼항 > 대입
3. 이항 연산자 우선 순위: 산술 > 비교 > 논리
+) 참고
* 아무리 성능 좋은 cpu여도 오차는 무조건 존재한다.
* jvm 이 할당받아 이용하는 메모리 영역
'정리 노트 > 꿈날개_JAVA_기초' 카테고리의 다른 글
12. Scanner Class (입력 스트림) + 실습 ④ (0) | 2023.06.18 |
---|---|
11. 이진법과 보수, 리터럴과 접미사 / 진수와 접두사 (0) | 2023.02.07 |
10. 변수의 기본 값, 지역변수와 초기화 (0) | 2023.02.07 |
9. 문자와 문자열 (더하기 연산과 공백 저장) (0) | 2023.02.07 |
8. 형 변환과 오버플로우 (변수 실습②,③) (0) | 2023.02.07 |