본문 바로가기

코딩 국비 학원/Do it! 자바 프로그래밍 입문

[Do it! 자바 프로그래밍 입문]비트 연산자, 조건문

12.12.02 배운 내용 정리
(비트 연산자, 조건문)

 

비트 연산자

 

비트 연산자 = 비트 단위로 연산이 이루어지는 연산자

비트 단위의 연산을 하는 경우 =  '암호화' 작업처럼 임의의 숫자를 만들거나,

어떤 변수의 특정 비트를 꺼내보는(마스킹 : masking) 경우에 사용함.

혹은 하드웨어에 내장되는 임베디드 시스템 프로그램에서 메모리 용량이 부족하거나 계산이 복잡해서 속도가 느려질 때,

곱셈이나 나눗셈을 비트 이동 연산자를 사용하면 어떤 수의 2배수, 4배수를 만들어 속도를 빠르게 할 수 있음.

자바는 이런 환경은 아니지만 프로그램에서 특정 값을 만들거나 연산할 때 비트 연산자 사용

 

비트 논리 연산자

 

비트 논리 연산자 = 비트 단위로 &, |, ^, ~ 연산이 이루어짐

 

& 연산자

&(AND) 연산자 = 두 개의 비트 값이 모두 1인 경우에만 연산 결과 값이 1이 됨

ex. int num1 = 5;

      int num2 = 10;

      int result = num1 & num2;

→ 컴퓨터 내부에서는 5와 10이 비트 단위로 연산되기 때문에 2진수 형태로 연산됨

    num1 : 0  0  0  0  0  1  0  1  

& num2 :  0  0  0  0  1  0  1  0

    result :  0  0  0  0  0  0  0  0

→ 5와 10을 & 연산하면 결과 값은 0이 됨

 

| 연산자

|(OR) 연산자 = 비트 값이 하나라도 1이면 연산 결과 값이 1이 됨

ex. 5와 10을 |(OR) 연산한 결과는 2진수로 00001111이고, 10진수로 변환하면 15임

 

^ 연산자

^(XOR) 연산자 = 같은 값이면 0, 다른 값이면 1의 결과 값을 가짐

ex. 5와 10을 ^(XOR) 연산한 결과는 2진수로 00001111임

 

~ 연산자

~(반전) 연산자 = 비트 값을 0은 1로, 1은 0으로 바꿈

ex. int num = 10;

      int result = ~num;

→ num : 0  0  0  0  1  0  1  0

~  num : 1  1  1  1  0  1  0  1   //-11

위 경우는 부호 비트가 1로 바뀌었기 때문에 음수가 되었음

음수는 양수로 다시 변환해야 값이 얼마인지 알 수 있음

2진수 11110101을 10진수로 변환하면 11이 됨(00001010 → 00001011된거임)

따라서 ~num의 값은 -11임

 

비트 이동 연산자

 

비트 이동 연산자는 시프트 연산자라고도 하며 <<, >>, >>> 이렇게 세 가지가 있음

 

<< 연산자

<< 시프트 연산자 = 왼쪽으로 비트를 이동하는 연산자

ex. int num = 5;

     num << 2;

→ num           :  0  0  0  0  0  1  0  1

    num  <<  2  :  0  0  0  1  0  1  0  0

00000101을 두 비트만큼 왼쪽으로 이동함. 이때 앞 두자리 비트 00은 없어지고 뒷부분은 0으로 채워짐

왼쪽으로 n비트 이동한다는 것은 기존 값에 2ⁿ만큼 곱한다는 뜻임

따라서 왼쪽으로 2비트 이동한 00010100은 5\*2²=20, 즉 값 20이 됨

 

>> 연산자

>> 시프트 연산자 : 오른쪽으로 비트를 이동하는 연산자

ex. int num = 10;

     num >> 2;

→ num           :  0  0  0  0  0  1  0  1

    num  <<  2  :  0  0  0  0  0  0  1  0

오른쪽으로 n비트 이동하면 기존 값을 2ⁿ만큼 나눔.

위 경우 10/2²이 되므로 결과 값은 2가 됨

위 경우 왼쪽에 채워지는 비트 값는 기존 값의 부호 비트와 동일함

 

>>> 연산자

>>> 시프트 연산자 : >> 연산과 동일하게 비트를 오른쪽으로 이동함.

차이가 있다면 >>> 연산자는 왼쪽에 채워지는 비트 값이 부호 비트와 상관없이 무조건 0이 됨

비트를 이동했다고 해서 값이 바로 변하지는 않고, 결과 값을 직접 대입해줘야 값이 바뀜

 

 

연산자 우선순위

 

연산자의 일반적인 우선순위
- 단항 연산자가 가장 높고 이항, 삼항 연산자 순서
- 대입 연산자의 우선순위가 가장 낮음
- 산술, 관계, 논리, 대입 연산자 순서로 우선순위를 가지며 ( )의 우선순위가 가장 높음

 

우선순위 연산자 연산 방향
1 일차식 ( ), [ ], .
2 단항 !,  ++,   -- ,  +,  -
3 산술 %,  /
4 산술 +,  -
5 비트 이동 <<,  >>
6 관계 < >,  <=,  >=
7 관계 ==,  !=
8 비트 곱 &
9 비트 차 ^
10 비트 합 |
11 논리 곱 &&
12 논리 합 ||
13 조건 ?,  :
14 대입 =,  +=,  -=,  *=,  %=,  /=

 


3장 연습문제 풀이

① 소스 코드 빈칸 채우기

 - 변수에 값을 대입할 때 사용하는 연산자 → =

 - 왼쪽 변수 값과 오른쪽 변수 값이 같은지 비교하는 연산자 → ==

 - 조건식이 참인 경우와 거짓인 경우 다른 결과 값을 출력하는 연산자 → ? :

 

연습문제 1번

 

② 다음 코드가 수행될 때 출력값 구하기

int num;

num = -5 + 3 * 10 / 2;

System.out.println(num);    //나눗셈 우선 10 / 2 = 5, 그다음 곱하기 5 * 3 = 15, 그다음 뺄셈 15 - 5 = 10

 

다음 코드가 수행될 때 출력값 구하기

int num = 10;

 

System.out.println(num);        //10

System.out.println(num++);     //후위증가이므로 10

System.out.println(num);         //11

System.out.println(--num);       //전위감소이므로 10

 

다음 코드가 수행될 때 출력값 구하기

int num1 = 10;

int num2 = 20;

boolean result;

 

result = ((num1 > 10) && (num2 > 10));   

System.out.println(result);                        //num1이 10을 초과하지 않으므로 false

result = ((num1 > 10) || (num2 > 10));

System.out.println(result);                        //num2가 10을 초과하므로 true

System.out.println(!result);                       //결과값의 반대를 출력하므로 false

 

다음 코드가 수행될 때 출력값 구하기

int num1 = 2;                                       //00000010

int num2 = 10;                                     //00001010

 

System.out.println(num1 & num2);    //둘 다 1이어야 1이므로 00000010 = 2

System.out.println(num1 | num2);     //둘 중 하나만 1이어도 1이므로 00001010 = 10

System.out.println(num1 ^ num2);    //같은 값이면 0, 다른 값이면 1이므로 00001000 = 8

System.out.println(~num1);               //값을 반전시켜 출력하므로 11111101 → 음수이므로 양수로 변환 → 00000011 = -3

 

다음 코드가 수행될 때 출력값 구하기

int num = 8;                                    //00001000

 

System.out.println(num += 10);     //num값에 10을 더하므로 = 18

System.out.println(num -= 10);      //num값에 10을 빼므로 = 8

System.out.println(num >>= 2);     //00001000에서 오른쪽으로 두칸 밀어냄 → 00000010 = 2

 

다음 코드가 수행될 때 출력값 구하기

int num = 10;

int num2 = 20;

 

int result = (num >= 10) ? num2 + 10 : num2 - 10;   //num값이 10보다 크거나 같으므로 참(T) → num2 + 10값 출력 = 30

System.out.println(result);


조건문

 

조건문 = 주어진 조건에 따라 다른 문장을 선택할 수 있도록 프로그래밍하는 것

ex. '만약 나이가 8살 이상이면 학교에 다닌다'라는 문장에서는 '나이'가 조건이 되는 것임

 

if문과 if-else문

if문 = if문을 사용하는 형태를 간단히 나타내면 아래와 같음

ex. if(조건식) {

           수행문;         //조건식이 참일 경우에 이 문장을 수행

      }

주어진 조건식이 '참'일 경우에 중괄호 안에 있는 문장을 수행하며,

조건식에는 결과가 참, 거짓으로 판별되는 식이나 참, 거짓의 값을 가진 변수, 상수를 사용할 수 있음

연산의 결과가 참, 거짓이되는 관계 연산자를 자주 사용

 

ex. '만약 나이가 8살 이상이면 학교에 다닌다'라는 문장을 if문으로 나타내면 다음과 같음

int age = 10;

if (age >= 8)      //age값이 8 이상이면 아래 "학교에 다닙니다" 문장을 수행함

System.out.println("학교에 다닙니다");

 

 if-else문 = 조건식을 만족하는 경우와 만족하지 않는 경우를 모두 나타낼 때 사용함

ex. if(조건식) {

           수행문;         //조건식이 참일 경우에 이 문장을 수행

      }

      else {

           수행문2;         //조건식이 거짓일 경우에 이 문장을 수행

      }

주어진 조건식이 '참'일 경우에 if문 블록{  } 안에 있는 문장을 수행하고,

'거짓'일 경우에는 else문 블록{  } 안에 있는 문장을 수행함.

따라서 else문에는 '조건식'을 사용하지 않음  

 

if-else문을 그림으로 나타내면 아래 왼쪽 그림과 같고, 이를 순서도라고 부름

if-else문으로 '만약 나이가 8살 이상이면 학교에 다닌다. 그렇지 않으면 학교에 다니지 않는다'라는 문장을

순서도로 표현하면 아래 오른쪽 그림과 같음

 

 

※ 순서도 구성요소

요소 설명
모서리가 둥근 직사각형 프로그램의 시작과 끝을 나타냄
직사각형 변수를 선언하거나 대입하는 처리문을 나타냄
마름모 조건을 나타냄
화살표 프로그램의 흐름을 표현함

 

나이에 따라 다른 문장 출력

 

※ 제어문을 구현할 때는 중괄호{  } 쓰는 습관 들이기(가독성 ↑, 오류 방지),

+ 중괄호를 사용하면 블록 내부의 문장은 들여쓰기 해줘야함

 

if-else if-else문

if-else if-else문 = 하나의 상황에 조건이 여러개인 경우 사용

ex. if(조건식1) {

           수행문1;         //조건식1이 참일 경우 수행

      }

      else if(조건식2) {

           수행문2;         //조건식2이 참일 경우 수행

      }

       else if(조건식3) {

           수행문3;         //조건식3이 참일 경우 수행

      }

      else {

           수행문4;         //위의 조건이 모두 해당하지 않는 경우 수행

      }

      수행문5;              //if-else if=else문이 끝난 후 수행

 

ex. if-else if-else문으로 입장료 계산

놀이공원 입장료가 취학 전 아동(8살 미만)은 1,000원, 초등학생(14살 미만)은 2,000원,

중·고등학생(20살 미만)은 2,500원, 그 이상은 3,000원이라고 했을 때의 프로그램(순서도, 코드)

 

입장료 계산

 

※ if-else if문과 if-if문의 차이

 - if-else if문 : 하나의 조건을 만족하면 나머지 조건을 비교하지 않고 다음 수행문으로 넘어감

 - if-if문 : 조건마다 각각 비교함

따라서 코드를 작성할 때 하나의 상황에 여러 조건을 비교하는 경우에는 if-else if문으로 구현해야하고,

성별처럼 개별 조건을 비교해야 하는 상황이라면 if문을 따로 사용해야 함

 

조건문과 조건 연산자

if-else문은 조건 연산자로도 구현 가능함

ex. 서로 다른 두 수 a, b를 비교해서 둘 중 더 큰 수를 max 변수에 대입하는 코드를 구현할 때

if-else문과 조건 연산자를 사용한 코드는 다음과 같음

 

▶if-else문

if(a > b)

  max = a;

else

  max = b; 

 

▶조건 연산자

max = (a > b) ? a : b;

 

switch-case문

switch-case문은 조건이 하나의 변수 값이나 상수 값으로 구분되는 경우 사용함.

만약 조건이 복잡한 식으로 이루어진다면(ex. 10 < age < 20과 같은 경우) 적합하지 않음.

하나의 값으로 조건을 비교할 수 있을 때(ex. 학점 A, B, C)사용하는 것이 적합함.

 

조건식의 결과가 정수 또는 문자열 값이고 그 값에 따라 수행되는 경우가 각각 다른 경우

(ex. 경기에 참가한 선수의 순위에 따라 메달 색을 정하는 프로그램 등)에는

swich-case문으로 구성하는 것이 코드도 깔끔하고 가독성도 좋음

 

ex. switch(rank)  {

         case 1 : medalColor = 'G';

                      break;

         case 2 : medalColor = 'S';

                      break;

         case 3 : medalColor = 'B';

                      break;

         default : medalColor = 'A';

}

 

case문에는 여러 문장이 있어도 { }를 여러 번 사용하지 않음

 

case : ~break;까지가 조건에 해당하는 문장이며, rank 값이 1이면 case 1의 코드가 수행되고,

rank 값이 2이면 case 2, rank 값이 3이면 case 3의 코드가 수행됨.

만약 rank 값과 일치하는 case가 없다면 default 코드가 수행됨

 

 

case문은 여러 경우를 동시에 처리할 때도 자주 사용함

ex. 각 달의 날짜를 출력할 경우 case문의 값은 다르지만 수행문이 같은 경우

(ex. 1, 3, 5, 7, 8, 10, 12월 모두 day = 31인 것처럼)에는 다음과 같이 case문을 동시에 사용할 수 있음

case 1 : case 3 : case 5 : case 7 : case 8 : case 10 : case 12 : day = 31;

             break;

case 4 : case 6 : case 9 : case 11 : day = 30;

             break;

case 2 : day = 28;

             break;

 

※ switch-case문에서 break문의 역할

switch-case문에서 break문을 사용하지 않으면 첫 번째 case 조건을 만족하더라도 switch-case문을 빠져나오지 않음.

따라서 잇따라 나오는 문장까지 모두 수행되어서 맨 마지막 default문에 있는 값이 변수에 대입됨.

그렇기 때문에 switch-case문에서는 break문을 반드시 사용해야 함.

 

case문에 문자열 사용하기

자바 7부터는 switch-case문의 case 값에 정수 값뿐 아니라 문자열도 사용할 수 있음