3장 연산자

JAEUK KIM·2023년 1월 15일
0

자바의 정석

목록 보기
2/3

연산자 : 연산을 수행하는 기호
피연산자 : 연산 수행 대상

연산자의 우선순위는 상식적인 선에서 해결 가능
연산 방향은 왼->오 가 기본 but 대입, 단항(위치에 따라 다름)은 오->왼

산술변환 - 연산 직전 발생하는 자동 형변환
피연산자의 타입 일치시켜줌(같거나 크게) ex) int i =10; float f =20;                                                            float result = f+ (float)i;
작은 타입->큰타입 : 형변환 연산자 생략 가능
큰타입 -> 작은타입: 값 손실 발생하므로 X

단항연산자
증감 연산자 ++, -- :일반적으로 단항 연산자는 피연산자의 왼쪽에 존재하지만 증감 연산자는 양쪽 모두 가능하며 피연산자의 값을 1증감한다.

int i = 5;
i++ //증가 연산자가 뒤에 위치한 후위형으로 i값을 불러온 후 1증가
++i //전위형 i의값을 1증가시킨 후 불러온다

int i =4, j= 4;
System.out.println(i++); //i값을 먼저 출력후에 1증가
System.out.println(++j); //j값을 1증가 후에 출력
System.out.println("i="+ i +", j = "+j);

실행결과
4
5
i=5 , j= 5

※하나의 식에서 한 변수가 중복해서 나올때 증감 연산자를 사용하는 것은 지양 ex) x= x++ - ++x


산술연산자
int 타입끼리 나눌시 소수점이 나오면 버려짐 why? 타입이 실수형이기 때문에
int 10/ int 4 = 2
한쪽 실수형 한쪽 정수형일땐 형변환을 통해 큰 타입의 결과값이 출력
10/ 4.0f = 2.5f
나누는 수로 0 사용금지!

연산할 시에는 결과값을 예측해서 범위에 맞는 연산타입을 쓰는것이 중요!

long c = 1000000 * 2000000;
       = -12412381 //피연산자의 타입이 두개 다 long보다 작은 int이기 때문에 값손실 발생
long c = 1000000L*2000000; //어느 한쪽에 접미사L 붙여서 형변환

int 10000000*10000000;
   =-142412379 //int타입에 저장 가능한 값의 범위를 초과했기 때문에 오버플로우 발생

문자 - 문자 =숫자로 변환 가능 ↓문자와 숫자의 유니코드를 활용

char c1 ='a';
char c2= c1+1; //에러발생  둘다 char로 형변환을 안해주었지만 아래 코드는 정상 실행 why? c1은 변수이고 'a'는 리터럴로 봄
char c3= 'a'+1; // 리터럴간 연산에서는 컴파일러가 미리 연산을 수행하고 그 결과로 코드를 최적화 한다. 변수는 해당X
컴파일 후 c3의 코드는
char c3= 'b' 

나눗셈 결과를 반올림 하는 메서드 Math.round()와 나머지 연산자%

double pi = 3.141592;
double shortpi = (int)(pi*1000)/1000.0; //pi는 실수형이지만 인트형으로 형 변환 했기 때문에 1000을 곱한 후 소수점 이하 나머지는 버려진다.
System.out.println(shortpi);
결과:3.141 -

반올림 하는 방법 1
double shortpi = (int)(pi*1000+0.5)/1000.0 //0.5를 더해서 올려준다
결과: 3.142

방법 2 Math.round()메서드 사용
double shortpi = Math.round(pi*1000)/1000.0
결과:3.142
Math.round() - 매개변수 값을 소수점 첫째 자리에서 반올림후 그 값을 정수로 반환해준다.

System.out.println(-10%8)// 나머지 연산자는 부호를 무시하고 연산한 후
System.out.println(10%-8)//나온 값에 왼쪽 피연산자의 부호를 붙여서 결과 출력
System.out.println(-10%-8)
결과:-2 , 2, -2

비교 연산자

연산 결과는 true or false로 반환하기 때문에 조건문 혹은 반복문에서 사용된다.

**등가비교 연산자 - 대소비교 연산자와 다르게 모든 자료형에서 사용 가능
== 피연산자의 값이 같으면 true 아니면 false
10 == 10.0f 
결과:true
!= 값이 다르면 true 아니면 falsefloatdouble
float의 값을 double로 형변환 해도 float의 값은 달라지지 않는다 
따라서 정밀도가 낮은 float의 값과 높은 double을 비교하면 결관는false

오차범위를 감안해서 doublefloat형으로 형변환 시킨 후 
두 타입의 앞 몇자리만 떼어내서 비교 할 수밖에 없음

**문자열끼리 비교
==연산자 사용 대신에 equals()메서드 사용
String은 원래 클래스여서 객체를 생성해 주어야 하지만 예외적으로 객체 생성 없이
사용 가능
String str = "acg";
System.out.printf("str.equals(\"acg"\) ? %b%n" , str.equals("acg")); 

결과 : str.equals("acg") ? true

논리연산자

||(or) 피연산자 중 한 쪽만 true이면 결과가 true
&(and) 피연산자 둘 다 true여야 결과 true
! 논리부정 연산자 truefalsefalsetrue로
효율적인 연산을 위해선 원하는 원산 결과값을 얻을 수 있는 피연산자를 
왼쪽에 배치하는 것이 좋음 -왼쪽부터 연산하기 때문에
ch = 'c'
System.out.printf("ch=%c , 'a'<= ch && ch <='z' = %b%n , ch ,
'a'<= ch && ch <='z' );
결과 : ch = c, 'a'<= ch && ch <='z' = true

ch는 대문자가 아니다 라는 조건case 논리부정!
c <'A' || c > 'z' ---> !('A'<= c&&c <='Z');

비트 연산자
비트 단위로 데이터 값을 연산하기 때문에 0,1로 표현할 수 있는 정수형만 가능

  • 비트 논리 연산자
    |연산자|논리|설명|
    | & |And|피연산자 양쪽 모두 1이어야 결과로 1을 얻음|
    | | |Or |피연산자 중 어느 한쪽이 1이면 1 얻음|
    | ^ |Xor|피연산자의 값이 서로 다를때만 1 얻음|
    | ~ |Not|피연산자의 값 반전|



System.out.println("15 & 25 = " + (15 & 25)); 
System.out.println("15 | 25 = " + (15 | 25)); 
System.out.println("15 ^ 25 = " + (15 ^ 25)); 
System.out.println("~25 = " + (~25)); 

결과
15 & 25 =9
15 | 25 =31
15 ^ 25 =22
  ~25 = -26

비트 이동 연산자 << , >>

연산자설명
<<2진수로 표현한 피연산자의 각 자리수를 오른쪽으로 이동
>>왼쪽으로 이동


x<<n , x>>n은 x*2ⁿ, x/2ⁿ과 같다
쉬프트 연산자는 곱하기와 나누기보다 빠른 실행속도가 장점이지만 코드의
가독성을 위해 곱셈과 나눗셈을 주로 사용하고 빠른 실행을 요구하는 곳에만
쉬프트 연산자를 사용하는 것이 좋다.

삼항 연산자와 복합 대입 연산자

조건식 ?1:2  - 조건식이 참이면 식1을 반환하고 거짓이면 식2를 반환
x:6 y:3
result = (x>y) ? x:y; 
 result = (6>3) ? 6:3;
  result = (true) ? 6:3;
   result = 6;


※ i *= 10+j     i = i(10+j);
우변에 항이 둘 이상일 때

profile
Think less, Do it now

0개의 댓글