Back-End/JAVA

[JAVA] 자바의 정석(기초편) 공부 - CHAPTER 3 . 연산자

남건욱 2023. 5. 31. 20:23
반응형
연산자와 피연산자

 

x + 3
// x와 3은 피연산자  '+'는 연산자

연산자는 '연산을 수행하는 기호'를 말한다. +기호는 덧셈 연산을 수행하며 '덧셈 연산자'라고 한다. 자바에서는 사칙연산(+, -, *, /)을 비롯해서 다양한 연산자를 제공한다. 연산자가 연산을 수행하려면 반드시 연산의 대상자가 있어야 하는데, 이것을 '피연산자(operand)'라고 한다.

 

 

 

 

연산자의 종류
종류 연산자 설명
산술 연산자 +  =  *  /  %  <<  >> 사칙 연산과 나머지 연산(%)
비교 연산자 >  <  >=  <=  ==  != 크고 작음과 같고 다름을 비교
논리 연산자 &&  ||  !  &  |  ^  ~ '그리고(AND)'와 '또는(OR)'으로 조건을 연결
대입 연산자 = 우변의 값을 좌변에 저장
기타 (type) ?: instanceof 형변환 연산자, 삼항 연산자, instanceof연산자

피연산자의 개수로 연산자를 분류하기도 한다. 피연산자의 개수가 하나면 '단항 연산자', 두 개면 '이항 연산자', 세 개면 '삼항 연산자'라고 부른다. 대부분은 '이항 연산자'이다. 

 

 

 

-3 -5

위의 식에는 두 개의 연산자가 포함되어 있다. 둘다 같은 기호로 ' - '를 나타내지만 엄연히 다른 연산자이다. 왼쪽은 '부호 연산자'이고, 오른쪽은 '뺄셈 연산자'이다. 이처럼 서로 다른 연산자의 기호가 같은 경우도 있는데, 이럴 때는 피연산자의 개수로 구분이 가능하다.

 

 

 

 

 

연산자의 우선순위
5 + 3 * 4

식에 사용된 연산자가 두개 이상인 경우에는 연산자의 우선순위에 의해서 연산순서가 정해진다. 곱셈과 나눗셈은 덧셈과 뺄셈보다 우선순위가 높다는 것은 우리가 이미 수학에서 배워서 알고 있을 것이다. 그래서 위의식은 5+3보다 3*4를 먼저 수행한 후 그 결과에 5를 더해서 17이 되는 것이다. 대부분 상식선에서 해결된다.

 

 

 

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

 

 

 

 

 

증감 연산자 ++, --
증가 연산자(++) 피연산자의 값을 1 증가시킨다.
감소 연산자(--) 피연산자의 값을 1 감소시킨다.

일반적으로 단항 연산자는 피연산자의 왼쪽에 위치한다. 증가 연산자와 감소 연산자는 양쪽 모두 사용 가능하다. 피연산자의 왼쪽에 위치하게되면 전위형(prefix), 오른쪽에 위치하면 후위형(postfix)라고 한다.

 

 

 

타입 설명 사용예
전위형 값이 참조되기 전에 증가시킨다. j = ++i;
후위형 값이 참조된 후에 증가시킨다. j = i++;

 

 

 

 

 

부호 연산자

부호 연산자' - '는 피연산자의 부호를 반대로 변경한 결과를 반환한다. 피연산자가 음수이면 양수, 양수이면 음수로 결과가 정해진다. 부호연산자' + '는 하는 일이 없다. 부호 연산자는 boolean형과 char형을 제외한 기본형에만 사용할 수 있다.

 

 

 

 

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

코딩을 하다 보면 같은 타입뿐만 아니라 서로 다른 타입 간의 연산을 수행하는 경우도 있다. 이럴 때는 연산을 수행하기 전에 타입을 일치시켜야 하는데, 변수나 리터럴 타입을 다른 타입으로 변환하는 것을 '형변환(casting)'이라고 한다.

 

 

 

double d = 85.4;
int score = (int)d;

두번째 줄의 연산과정
int score = (int)d;  ->  int score = (int)85.4;  ->  int score = 85;

여기서 사용되는 괄호()는 '캐스트 연산자' 또는 '형변환 연산자'라고 한다. 형변환을 '캐스팅(casting)'이라고도 한다.

이 과정에서 보이듯이, 형변환 연산자는 그저 피연산자의 값을 읽어서 지정된 타입으로 형변환하고 그 결과를 반환할 뿐이다. 그래서 피연산자인 변수 d의 값은 형변환 후에도 아무런 변화가 없다.

 

 

 

 

 

자동 형변환
float f = 1234;  // float f = (float)1234;에서 (float)가 생략됨
byte b = 1000;  // 오류 byte타입의 범위(-128 ~ 127)을 벗어난 값의 대입
byte b = (byte)1000;   //  오류는 발생하지않지만, 값 손실이 발생. b에는 -24가 저장된다.

서로 다른 타입 간의 대입이나 연산을 할때 타입을 일치시키는 것이 원칙이지만 경우에 따라 편의상의 이유로 형변환을 생략할 수 있다. 그렇다고 형변환이 이루어지지 않는 것이 아니라 컴파일러가 생략된 형변환을 자동적으로 추가해 준다.

형변환은 "기존의 값을 최대한 보존할 수 있는 타입으로 자동 형변환된다." 값 손실이 최대한 적은 쪽으로 형변환된다.

 

 

int형  float형        float형     float형        float형
10   / 4.0f      ->   10.0f   /   4.0f     ->    2.5f

int형 10을 float형 4.0f로 나눴을 때의 과정이다. 4바이트인 int형을 8바이트인 float형으로 형변환 한 뒤에 연산을 수행한다. 이유는 두 개 중 범위가 넓은 타입으로 형변환되기 때문이다.

 

 

 

 

 

 

Math.round()
long result = Math.round(4.52)  // result에 5가 저장된다.

반올림을 하려면 Math.round()를 사용하면 된다. 이 메서드는 소수점 첫째 자리에서 반올림한 결과를 정수로 반환한다.

만약 소수점 첫째 자리가 아닌 다른 자리에서 반올림하려면 10의 n제곱으로 적절하게 곱해주고 나누어줘야 한다.

 

 

 

 

 

나머지 연산자
int x = 10;
int y = 4;
int z;

z = x % y;    // z에는 x에서 y를 나눈값의 나머지인 2가 들어간다.
z = 2;

나머지 연산자는 왼쪽의 피연산자를 오른쪽 피연산자로 나누고 난 나머지 값을 결과로 반환한다. 나눗셈에서는 나누는 수(오른쪽 피연산자)로 0을 사용할 수 없고, 피연산자로 정수와 실수를 허용한다. 나머지 연산자는 주로 짝수, 홀수, 배수 검사 등에 주로 사용된다.

 

 

 

 

 

비교 연산자
비교연산자 연산결과
> 좌변 값이 크면 true 아니면 false
< 좌변 값이 작으면 true 아니면 false
>= 좌변 값이 크거나 같으면 true 아니면 false
<= 좌변 값이 작거나 같으면 true 아니면 false

참이면 true 거짓이면 false를 결과로 반환한다. 기본형 중에서는 boolean을 제외한 나머지 자료형에 다 사용할 수 있지만 참조형에는 사용할 수 없다.

 

 

 

비교연산자 연산결과
== 두 값이 같으면 true 아니면 false
!= 두 값이 다르면 true 아니면 false

==는 두 값이 같으면 true,!=는 두 값이 다르면 true이다.

 

 

 

 

 

 

문자열의 비교, equals() 메서드
String str = new String("wook");

boolean result = str.equals("wook");

str안에는 "wook"이라는 문자열을 초기화시켜주었다. 그 후 true, false값을 가질 수 있는 boolean형의 result를 생성해준 뒤 str.equals("wook")을 사용해서 str안의 문자열과 "wook"과 일치하는지 체크하였다. 일치하면 result안에 true가 들어갈 것이고 불일치하게 된다면 result안에 false가 들어갈 것이다.

 

 

 

 

 

논리 연산자 && ||
x y x || y x && y
true true true true
true false true false
false true true false
false false false false

|| (OR 연산자)는 피연산자 중 어느 한쪽이 true이면 true를 반환한다.

&& (AND 연산자)는 피연산자 양쪽 모두 true이어야 true를 반환한다.

 

 

 

 

 

 

논리 부정 연산자!
x !x
true false
false true

간단하다. 피연산자가 true이면 false로 바꿔주고, 피연산자가 false이면 true로 바꾼다.

이러한 성질을 이용하면 한번 누르면 켜지고, 다시 누르면 꺼지는 TV의 전원 버튼과 같은 '토클버튼(toggle button)'을 논리적으로 구현할 수 있다.

 

 

 

 

 

 

조건 연산자
조건식 ? 식1 : 식2
조건식이 true면 식1을 실행, 조건식이 false면 식2를 실행

조건 연산자는 세 개의 피연산자를 필요하는 삼항 연산자이며, 삼항 연산자는 조건 연산자 하나뿐이다.

가독성을 높이기 위해 조건식을 괄호()로 둘러싸는 경우도 많다. 하지만 필수는 아니다.

ex) result = (x > y)? x : y ;

또한 피 연산자의 타입이 다른 경우에는 이항 연산자처럼 형변환이 자동으로 이루어진다.

 

 

 

 

 

 

복합 대입 연산자
i += 3; i = i + 3;
i -= 3; i = i - 3;
i *= 3; i = i * 3;
i /= 3; i = i / 3;
i %= 3; i = i % 3;
i <<= 3; i = i << 3;
i >>= 3; i = i >> 3;
i &= 3; i = i & 3;
i ^= 3; i = i ^ 3;
i |= 3; i = i | 3;

대입 연산자는 다른 연산자와 결합하여 다음과 같이 사용할 수 있다. 결합된 두 연산자는 반드시 공백이 없이 붙여 써야 한다.

 

 

 

 

 

 

자바의 정석(기초편) CHAPTER 3. 연습문제

 

3-1 문제

답은 4,5번이다. 

1번 byte형식인 변수 b에 int형이 들어가 야하기 때문에 반드시 형변환이 필요하다.

2번 char형식인 ch변수에 b를 넣어주려면 범위가 다르기 때문에 형변환이 필요하다.

3번 char, short는 둘 다 2byte이다. 하지만 범위가 다르기 때문에 형변환이 필요하다.

4번 I는 long형인 8byte이고 변수 f는 4byte 크기의 float형이기 때문에 생략이 가능하다.

5번 정수형 4바이트 변수 i에 char형이고 크기가 2byte인 변수가 들어갈 때는 형변환을 생략하고 적어도 된다.

 

 

 

 

 

 

3-2 문제

class Exercise3_2 {
public static void main(String[] args) {
int x = 2;
int y = 5;
char c = 'A'; // 'A' 65 의 문자코드는
System.out.println(1 + x << 33);
System.out.println(y >= 5 || x < 0 && x > 2);
System.out.println(y += 10 - x++);
System.out.println(x+=2);
System.out.println( !('A' <= c && c <='Z') );
System.out.println('C'-c);
System.out.println('5'-'0');
System.out.println(c+1);
System.out.println(++c);
System.out.println(c++);
System.out.println(c);
}
}
정답
6
true
13
5
false
2
5
66
B
B
C

 

앞서 내용을 제대로 숙지했다면 설명은 따로 필요하지 않을 것이다.

 

 

 

 

 

 

3-3 문제

class Exercise3_3 {
public static void main(String[] args) {
int num = 456;
System.out.println(  (1)  );
}
}

나눗셈 연산자는 반올림을 하지 않고 버린다. 따라서 num/100을 먼저 해주면 4가 될 것이다. 이것에 다시 100을 곱해주면 400이 된다. 이를 이용하면 정답은 (num/100)*100을 넣어주면 된다.

 

 

 

 

 

3-4 문제

class Exercise3_4 {
public static void main(String[] args) {
int numOfApples = 123; // 사과의 개수
int sizeOfBucket = 10; // ( ) 바구니의 크기 바구니에 담을 수 있는 사과의 개수
int numOfBucket =
numOfApples/sizeOfBucket + (    (1)    ) ;
System.out.println(" :"+numOfBucket); 필요한 바구니의 수
}
}

사과의 개수를 바구니의 크기로 나눠주고 +1을 해주면 필요한 바구니의 수를 구할 수 있다. 저 안에 넣어줄 식은 사과의 개수를 바구니의 크기로 나눠서 나머지가 없다면 더할 필요가 없고, 나눴을 때 나머지가 존재하면 +1을 해줘서 바구니를 하나 더 추가해줘야 한다. 따라서 정답은 numOfApples% sizeOfBucket > 0? 1 : 0 응해줘서 0보다 크면 1을 더해주고 0보다 크지 않을 때는 0을 더해준다.

 

 

 

 

 

 

3-5 문제

class Exercise3_5 {
public static void main(String[] args) {
int num = 10;
System.out.println(num > 0 ? "양수" :      (1)      )
}

num > 0이면 양수를 출력하고 (1)에 들어갈 것은 음수를 출력할 것이다. 간단하게 "음수" 라고 넣으면 된다. 하지만 0까지 출력해주어야 한다. 따라서 삼항 연산자를 하나 더 추가해줘야한다. num < 0? "음수" : 0 이라고 넣어주게 되면 num < 0 이면 "음수"라고 출력될것이고 둘다 포함이 되지않는다면 0을 출력할것이다. 정답은 (num < 0 ? "음수" : 0)이다.

 

 

 

 

 

3-6 문제

class Exercise3_6 {
public static void main(String[] args) {
int fahrenheit = 100;
float celcius =  (1)     ;
System.out.println("Fahrenheit:"+fahrenheit);
System.out.println("Celcius:"+celcius);
}
}

문제에서 변환공식은 '5/9f * (F-32)'라고 나와 있다.

이제 그대로 넣어보겠다.

5.9 * (fahrenheit - 32)이다. int형으로 사용 중이지만 double형으로 출력해야 하기 때문에 5.9 뒤에 f 접미사를 추가해 준다.

5.9f * (fahrenheit - 32) 해준 값에서 100을 곱하고 0.5를 더한 뒤에 int로 형변환하여 정수형으로 변경뒤,

다시 100으로 나누어서 소수점 셋째 자리에서 반올림해주면 된다.

따라서 공식은 (int)((5/9f * (fahrenheit - 32)) * 100 + 0.5) / 100f이다.

두줄로 나눠서 작성이 가능하다면 다음과 같이도 작성할 수 있다.

float celcius = (5/9f * (fahrenheit - 32));

celcius = (int)(celcius * 100 + 0.5) / 100f;

 

 

 

 

 

정리

챕터 3은 생각보다 내용은 많았지만 문제풀이나 개념이해등에 어려움은 없었다. 처음 배울 때는 이 부분이 익숙지 않아서 AND 연산자, OR연산자, NOT연산자 등 헷갈리는 게 많았다. 문제풀이를 하며 틀리고 해설보고 이것을 반복하다 보니 이제 머릿속에 들어온 것 같다. 문제풀이시 ++i와 i++를 무심코 지나간 적도 있기 때문에 앞으로 코딩을 할 때는 이 부분도 무심코 넘기지 않고 자세히 생각하며 코딩해야겠다. 

반응형
프로필사진

남건욱's 공부기록