본문 바로가기

Computer Engineering

[C] 0x07 조건문(Switch)

From Evernote:

[C] 0x07 조건문(Switch)

어제는 if 조건문  에 대해서 알아보았다. 어제에 이어서 조건문 Switch 에 대해 알아보자!!

switch(변수값)
{
     case 조건 :
          // 해당 조건에 만족할 경우 어떤 명령을 수행할지 명령문을 적어준다.
          break;
}

switch 문 : 변수에 해당하는 case 조건 ~ break문을 만나기 전까지 모두 수행한다.

**주의사항** : if문과 다르게 case 조건 :
=> 이 부분에 비교 / 논리 연산자를 사용할 수 없다.
범위를 표현할 수도 없다. 그리고 조건에는 정수로 표현해야한다. (실수를 사용할 수 없다.)

case 조건 : 의 예)

case ch >= 'A' && ch <= 'Z' :    // 이런식의 비교 연산자를 사용할 수 없는것이다.

case (5/2) :                               // 5/2 == 2 이기 때문에 사용할 수 있는 표현이다.
                                                    2.5 라고 생각하셨던 분들이 있었다면 ... 
여기 로 가셔서 연산자에 대해 공부하고 오세요.

그리고 
case 조건 :
     break;
default :
     // case 에 적은 조건 이외의 경우에 이 부분에 적은 명령문을 수행한다.
     break;

아래의 예제를 통해서 자세히 알아보자!

/*
점수를 입력받아 등급을 출력하는 프로그램을 작성해보자.
(단, 점수는 0~100점까지만 입력 가능하며, 그 외 점수를 입력하면 잘못된 입력임)
◈ [90점 이상 : A등급], [80점 이상 : B등급], [70점 이상 : C등급], [60점 이상 : D등급], [60점 미만 : F등급]
*/

#include <stdio.h>
#include <stdlib.h>

int main()
{

 int score,result;
 char grade;

 printf("점수 입력 : ");
 scanf("%d", &score);  // 입력을 받기위한 부분
 result = score / 10;     // 등급을  구분해주기 위한 변수

 switch(score >> 31)
 {
      case -1 :
       puts(" - 값은 음수자나~~~!!");
       exit (0);
      default :     // 0 이상인 경우
       switch (score / 101 )
       {
         case 0:                // 101보다 작은경우
             switch(result)
             {
                  case 10 :
                  case 9 : grade = 'A'; break;
                  case 8 : grade = 'B';  break;
                  case 7 : grade = 'C'; break;
                  case 6 : grade = 'D'; break;
                  default : grade = 'F';  break;
              }
             printf("%d점은 ==> %c등급\n",score,grade);
             break;

       default : puts("0~100점 사이의 값을 입력해주세요");           // 101 이상의 값이 입력된 경우
       exit (0);
      }
 }
 return 0;
}
===========================================================================

위에서 switch( score >> 31 ) 에 대해서 자세히 알아보자.
>>     // 이 표시(?)를 처음 볼 것이다. >>(<<) 을 쉬프트(시프트, shift) 연산자고 한다.

= 시프트 연산자란? =
줄리어스 시저의 암호문에서 유래된 연산자이다.  
DWWDFN => ATTACK  알파벳을 3칸 이동하면 원문이 나오는 것이다.

int sootja = 1;
sootja >> 1     // int 의 사이즈는 32bit. sootja 가 실제 컴퓨터에 들어간 것을 확인하면
                         0   0   0   0   ..... 0   0   0   1
                         |    |    |    |          |     |    |    |
          2의 n승 31 30 29 28 .....   3   2   1   0 

2의 0승만 1이라는 값이 들어가고 나머지 비트의 값은 0 이 되어서 계산을 하면 0 이 나오는 것이다.
그리고 31은 최상위비트(MSB)로 값을 표현하는데 사용되는 것이 아니라
부호(음수/양수)를 판별하는데 사용이 된다.
MSB가 0인 경우 = 양수 , 1인 경우 = 음수 로 판별하는 것이다.

쉬프트 연산자는 >> , << 이렇게 두 종류가 있다.
쉬프트 연산자는 >> , << 이렇게 두 종류가 있다.

12 >> 2
12를 2진수로 나타내면  0 0 0 0 .... 1 1 0 0 이다.
 >> 2 라는 표현은 >>(오른쪽) 으로 비트를 2칸 이동 하는 것이다.
이 말을 그림으로 나타내면
     0 0 0 0 .... 1 1 0 0
=>       0 0 0 0 .... 1 1 
이렇게 되는 것이다. 0 0 0 0 .... 1 1 값을 십진수로 표현하면 3이 된다.

>> 을 '비트단위 나눗셈'이라고도 말한다.

12 >> 2 == 12 / 2^2 
비트의 자리수(n)는 2의 n승(이하 2^n)이다. 
12 >> 2
=> 이 표현을 풀어쓰면 2^2 으로 12를 나누어 준 값과 동일하다.
그래서 비트단위 나눗셈이라고 하는 것이다.

반대로 << 는 '비트단위 곱'이라고 한다. 

아래의 예제를 실행시켜 보면 확실하게 이해할 수 있을 것이다.

#include <stdio.h>

int main()
{
  int a = 12;
  printf("12 >> 2 : %d\n" , a >> 2); // >> - 비트단위 나눗셈
  printf("12 << 2 : %d\n" , a << 2); // << - 비트단위 곱

  return 0;
}

해당소스를 컴파일해서 실행시켜 보자!
jack2@Security:~/바탕화면/C/0x07$ ./쉬프트연산자 
12 >> 2 : 3
12 << 2 : 48

12 >> 2 는 12 / 2^2 한 값인 3이 나온다. 그리고 12 << 2 는 12 * 2^2 한 값인 48이 나온다.

이제 어느 정도 이해가 되었다고 가정하고 우리가 원래 예제로 만들었던 소스 설명으로 돌아가 보자.

switch( score >> 31 )
=> score 의 비트자리수를 >>(오른쪽) 으로 31칸 이동을 하는 것이다.

score 가 양수로 입력된 경우에는 31자리 이동을 해서 0 이 될 것이다.
위에서 계속 공부했듯이 양수의 값이 들어가면 MSB가 0 이 되면서 빈 공간에 0 이 채워지는 것이다.

반면에 음수의 경우는 MSB 가 1이다. -1 을 예로 들면, 비트 단위로 보면 1111 ..... 1111 이렇게 표현이 된다.
1 0 0 0 .... 0 0 0 1 이거 아니냐고 하시는 분이 있으시다면  보수의 개념에 대해서 공부를 하시면 알 수 있습니다.

그 결과 음수가 입력이 되면 31 자리를 이동해서 빈 공간에 1 1 1 1 .... 1 1 1 1 이렇게 입력이 된다.
즉, -1 이 되는 것이다. 
그래서 case -1 : 의 경우에는  - 값은 음수자나~~~!! 를 출력하게 된다.

그리고 하나의 break; 는 하나의 { } (중괄호) 부분만 탈출(?)하게 된다.
그래서 위의 예제처럼 중첩 switch문을 사용하는 경우 break;를 정확하게 사용해야 탈출가능하다.

>> , << (시프트 연산자) 에 대해서 알아본 만큼 시프트 연산자처럼 비트를 가지고 노는(?) 비트연산자를 몇 가지 더 알아보자.

= ^ (XOR) =
: 두 비트가 같으면 0 // 다르면 1 로 만들어주는 것이다.
그냥 이렇게 말로 설명하면 또 헷갈려 하는 분들이 있을 수 있으므로 예제를 통해서 알아보자.

ex) XOR
#include <stdio.h>

int main()
{
  int a = 12;
  printf("12 ^ 12 : %d\n" , a ^ 12);
  printf("12 ^  2 : %d\n" , a ^  2);

  return 0;
}
=====================================================
처음 12 ^ 12 를 했을 경우 비트단위로 보면 1 1 0 0 ^ 1 1 0 0 이다
               1 1 0 0
           ^  1 1 0 0             //해당 비트가 같으면 0 다르면 1로 표현해 준다고 했으니 보면
          ----------------
               0  0 0 0            => 모든 비트가 같기때문에 모든 비트가 0 이 된 것이다.

다음으로 12 ^ 2 를 했을 경우 비트 단위로 나타내면 1 1 0 0 ^ 0 0 1 0 이다.
               1 1 0 0
          ^   0 0 1 0
          ---------------
               1 1 1 0            => 값이 다른 비트는 1로 동일한 값인 비트는 0으로 한 결과 1 1 1 0 이 된 것이다.

실제 소스를 컴파일해서 실행파일을 수행해보자.

실행결과)
jack2@Security:~/바탕화면/C/0x07$ ./XOR 
12 ^ 12 : 0
12 ^  2 : 14
=> 우리가 계산값으로 출력이 된 것을 확인할 수 있다.

= & (AND) =
: 각 자리수에 해당하는 비트값이 같으면 원래비트로 표시하고
                                  비트값이 다르면 0으로 표시하는 것이다.
이번에도 예제를 통해서 알아보자.
#include <stdio.h>

int main()
{
  int a = 12;
  printf("12 & 12 : %d\n" , a & 12);
  printf("12 &  2 : %d\n" , a &  2);
  printf("12 &  11: %d\n" , a &  11);

  return 0;
}

 12 & 12 => 1 1 0 0 & 1 1 0 0

=>                1 1 0 0
               &   1 1 0 0
              -----------------
                    1 1 0  0      => 모든 값이 동일하므로 모든 자리 모두 원래비트값으로 되어서  1 1 0 0 이 되는 것이다.

 12 & 2 => 1 1 0 0 & 0 0 1 0

=>              1 1 0 0
               & 0 0 1 1
          -------------------
                   0 0 0 0      => 모든 자리수의 비트값이 다르기 때문에 모두 0 이 되어서 0 0 0 0 이 된다.

 12 & 11 => 1 1 0 0 & 1 0 1 1

=>                1 1 0 0
               &   1 0 1 1
            -------------------
                    1 0 0 0     => 맨앞자리의 비트만 동일해서 1이 되고 나머지 비트는 다르므로 0 이 되어 1 0 0 0 이 된다.

실행결과)
jack2@Security:~/바탕화면/C/0x07$ ./bitAND 
12 & 12 : 12
12 &  3 : 0
12 &  11: 8

Posted via email from zzackzack2's Space

'Computer Engineering' 카테고리의 다른 글

[c] 0x0D 함수(Function)  (0) 2012.01.25
KLDPWiki: Emacs Change Fonts (Emacs 글꼴 바꾸기)  (0) 2012.01.25
[C] 0x06 조건문(if)  (0) 2012.01.12
[C] 0x05 연산자(Operator)  (0) 2012.01.11
[C] 0x03 DataType(자료형)  (0) 2012.01.09