Java/자바의 정석

[ch3] 연산자

정호나 2024. 6. 18. 18:25

연산자 : 연산을 수행하는 기호 (+,-,*, /)

피연산자 : 연산자의 연산 수행 대상

 

"모든 연산자는 연산결과를 반환한다."

 

 

 

연산자 우선순위

 

 

 

연산자 결합 규칙

우선 순위 같은 연산자 있을 때

 


1. 산술 > 비교 > 논리 > 대입. 대입은 제일 마지막에 수행
2. 단항 > 이항 > 삼항. 단항 연산자의 우선순위가 이항 연산자보다 높다
3. 단항 연산자와 대입 연산자를 제외한 모든 연산의  진행 방향은 왼쪽에서 오른쪽이다

 

 

증감 연산자

 

- 전위형 : 값이 참조되기 전에 증가시킨다. ++i를 위로 올림

- 후위형 :  값이 참조된 후에 증가시킨다. ++i를 아래로 내림

 

증감연산자가 독립적으로 사용된 경우. 전위형과 후위형은 차이가 없다.

 

부호 연산자

'+': 아무런 일도 하지 않음(실제 사용x)

 

형변환 : 변수 또는 상수의 타입을 다른 타입으로 변환하는 것

(타입) 피연산자

 

double d = 85.4;

int score = (int) d;

 

[처리순서]

int score = (int)85.4;

int score = 85;

 

컴퓨터는 문자를 저장할 수 없어. 문자를 숫자로 변환해야 해

 

자동 형변환 : 컴파일러가 자동으로 형변환

float f =1234;
float f = (float)1234;

int i = 3.14f; //"값손실 발생", float타입을 int타입에 넣으면 큰걸 작은거에 넣으니깐 에러
int i = (int)3.14f; //수동형 변환

 

 

2) 4byte를 1byte에 넣으면 값손실 있음. 직접 형변환해줘야 해

 

작은 값을 큰 값으로 넣을 때만 형변환 생략가능해서 자동 형변환 됨

 

short(+-3만)<->char 는 범위가 달라서 형변환 안돼

 

 

byte b = 100; //가능, byte타입의 범위의 값 대입
byte b = (byte)100 //가능, byte타입으로 형변환하여 대입

int i =100;
byte b =i;	//에러, int타입을 byte타입에 대입. 변수i에 뭐가 들었는지 컴파일러가 알 수 없어서
byte b = (byte)i;	//OK. byte타입으로 수동형변환하여 대입

byte b = 1000;	//에러 byte 타입의 범위(-128~127)를 벗어난 값의 대입
byte b = (byte)1000;	//OK.값 손실이 발생해서 변수 b에 -24(아무런 값) 저장됨

 

사칙연산자

int/int = int

int/float -> float/float(값손실 적은 쪽으로) -> float

 

산술 변환

"연산 전에 피연산자의 타입을 일치시키는 것"

1. 두 피연산자의 타입을 같게 일치시킨다(보다 큰 타입으로 일치)

2. 피연산자의 타입이 int보다 작은 타입이면 int로 변환된다

byte : -128~127

char : 0~6만

short : +-3만

 

반올림- Math.round()

: 실수를 소수점 첫째자리에서 반올림한 정수를 반환

 

long result = Math.round(4.52); //result에 5 저장

 

double pi = 3.141592;
double shortPi = Math.round(pi * 1000) / 1000.0;
System.out.println(shortPi);	//3.142

//처리 방식
//1. Math.round(pi*1000) /1000.0
//2. Math.round(3.141592 * 1000) / 1000.0
//3. Math.round(3141.592) / 1000.0
//4. 3142 / 1000.0
//5. 3.142


double shortPi = Math.round(pi * 1000) / 1000.0;	
System.out.println(shortPi);	//3.142

double shortPi = Math.round(pi * 1000) / 1000;		
System.out.println(shortPi);	//3, int로 나눔


System.out.println(pi*1000);	//3.141592
System.out.println((int)(pi*1000));	//3141
System.out.println((int)(pi*1000)/1000);	//3
System.out.println((int)(pi*1000)/1000.0);	//3.141

 

int 3142 / int 1000 = int 3

int 3142 / double 1000.0 => double 3142.0 / double 1000.0 => double 3.142

 

 

나머지 연산자 %

: 오른쪽 피연산자로 나누고 남은 나머지를 반환, 나누는 피연산자는 0이 아닌 정수만 허용(부호는 무시됨)

System.out.println(10 % 8);	//2
System.out.println(10 % -8);	//2

 

 

비교 연산자

'A' > 'B' => 65 >66 -> false

문자열 비교 시 == 대신 equals()사용해야 한다.

 

//보통 이렇게 사용
String str1 = "abc";
String str2 = "abc";
System.out.println(str1 == str2);	//true
System.out.println(str1.equals(str2));	//true


//9장에서 배움
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1 == str2);	//false
System.out.println(str1.equals(str2));	//true

 

논리 연산자 && ||

 

1. x는 10보다 크고 20보다 작다

10 <  x && x < 20

 

2. i는 2의 배수 또는 3의 배수이다 

i %2 ==0 || i % 3 ==0

 

3. i는 2의 배수 또는 3의 배수지만 6의 배수는 아니다 (괄호 꼭 쓰기) 

(i %2 == 0 || i %3 == 0) && i%6 != 0

 

4. 문자 ch는 숫자('0'~'9')이다

 

ch = '5'

'0' <= ch && ch <= '9'

유니코드로 바꿔서 풀기

 

5. 문자 ch는 대문자 또는 소문자이다.

('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') 

 

 

논리 부정 연산자 !

boolean b = true;

!!b ->  !!true -> !false -> ture

 

!는 단항연산자 (오른쪽에서 왼쪽으로 실행)

 

- 문자 ch가 소문자가 아니다.

ch < 'a' || ch > 'z'  <=>  ! ( 'a' <= ch && ch <= 'z' )

 

조건 연산자(삼항 연산자)

조건식 ? 식1 : 식2

 

result = (x > y) ? x : y ; //괄호 생략 가능

 

 대입 연산자

: 오른쪽 피연산자를 왼쪽 피연산자에 저장 후 저장된 값을 반환

 

System.out.println(x = 3);   //변수 x에 3이 저장되고

System.out.println(3);     //연산결과인 3이 출력된다

 lvalue : 대입 연산자의 왼쪽 피연산자, 저장공간,변수,배열

rvalue : 대입 연산자의 오른쪽 피연산자

 

int i = 0;

3 = i +3;    //에러. lvalue가 값을 저장할 수 있는 공간이 아니다

i + 3 = i;   //에러 lvalue의 연산결과가 리터럴(i+3 => 0+3 => 3)

 

final int MAX = 3;   //상수 

MAX 10;   //에러, 상수에 새로운 값을 저장할 수 없다.

 

복합 대입 연산자

i =  (i * (10 + j)); 괄호 꼭 치기