2011년6월3일_C과제6풀이(5의 배수, 10진수를 2진수로 변환, 주사위게임, 히스토그램), 예제2(call by value, call by reference)

 

 

C과제6 풀이

 
1. 두 정수 사이의 5의 배수의 갯수를 구하기

① 범위          n1(5) < x < n2(21)
② 반복          for(i = n1 + 1 ; i < n2 ; i++)
③ 비교              if(i % 5 == 0)
④ 증가                   cnt++;
⑤ 예외처리     if(n1 > n2)        n1과 n2교환.     //최소값이 최대값보다 큰 경우 값을 서로 교환.


2. 1Byte 범위의 정수를 입력 받아 각 비트의 값을 출력


num입력 받음.
① num & (1 << 0)   →  0번 비트
② num & (1 << 1)   →  1번 비트
③ num & (1 << 2)   →  2번 비트
④⑤⑥⑦ 생략.
⑧ num & (1 << 7)   →  7번 비트

결과가 0이면 0출력, 0이 아니면 1출력하게 하면 됨.

   1:  for(i = 0 ; i < 8 ; i++)
   2:  {
   3:      if(0 == ((1 << i) & num))
   4:      {
   5:          printf("%d : 0\n", i);
   6:      }
   7:      else
   8:      {
   9:          printf("%d : 1\n", i);
  10:      }
  11:  }


<다른 방법>
num입력 받음.
① (num >> 0) & 1   →  0번 비트
② (num >> 1) & 1   →  1번 비트
③ (num >> 2) & 1   →  2번 비트
④⑤⑥⑦ 생략.
⑧ (num >> 7) & 1   →  7번 비트

결과가 0또는 1이 나오므로 그대로 출력하면 되니 if( )문을 사용하지 않아도 되나 원본 데이터가 사라진다.

   1:  for(i = 0 ; i < 8 ; i++)
   2:  {
   3:      printf("%d : %d\n", i, 1 & (num >> i));
   4:  }


 

3. 주사위 게임

srand((unsigned)time(NULL));
unsigned는 unsigned int를 줄인 것. 시간값을 시드값으로 넣어 항상 다른 패턴으로 시작하도록 하는 함수.

for(i = 0 ; num > i ; i++)
    printf(“dice value : %d”, rand( ) % 6 + 1);

rand( )의 반환값을 6으로 나눈 나머지는 6을 넘을 수 없어 0 ~ 5사이의 값을 갖게 됨.
여기에 1을 더하면 1 ~ 6사이의 랜덤한 값이 얻어짐.

 

 

도전. 히스토그램

N1(7)    N2(2)    N3(5)
----------------------------
  *         *         *           6    1    4              (0보다 큰가 비교한 뒤에 *을 출력하고 -1시킴)
  *         *         *           5    0    3              (0보다 큰가 비교한 뒤에 *을 출력하고 -1시킴)
  *                   *           4    0    2              (N2는 0보다 크지 않으므로 공백문자를 출력함. N2는 감소하지 않음)
  *                   *           3    0    1              (0보다 큰가 비교한 뒤에 *을 출력하고 -1시킴)
  *                   *           2    0    0              (0보다 큰가 비교한 뒤에 *을 출력하고 -1시킴)
  *                               1    0    0              (N3가 0보다 크지 않으므로 공백문자를 출력함. N3도 감소하지 않음)
  *                               0    0    0              (0보다 큰가 비교한 뒤에 *을 출력하고 -1시킴)
                                  0    0    0              (N3가 0보다 크지 않으므로 공백문자를 출력함. N3도 감소하지 않음)

 

   1:  for(i = 0 ; i < 10 ; i++)
   2:  {
   3:      if(n1 != 0)
   4:      {
   5:          printf("*   ");
   6:          n1--;
   7:      }
   8:      else
   9:      {
  10:          printf("    ");
  11:      }
  12:      if(n2 != 0)
  13:      {
  14:          printf("*   ");
  15:          n2--;
  16:      }
  17:      else
  18:      {
  19:          printf("    ");
  20:      }
  21:      if(n3 != 0)
  22:      {
  23:          printf("*   ");
  24:          n3--;
  25:      }
  26:      else
  27:      {
  28:          printf("    ");
  29:      }
  30:  }


 

 

 

 

예제2


1. 입력 받은 정수를 교환한 후 출력

image

 


temp = N1;
N1 = N2;
N2 = temp;

 

 

 

2. swap( ) call by value

   1:  void swap(int val1, int val2)
   2:  {
   3:      int temp;
   4:   
   5:      temp = val1;
   6:      val1 = val2;
   7:      val2 = temp;    //내부에서 교환이 일어나고
   8:   
   9:      return ;    //아무것도 반환하지 않음.
  10:  }            //여기서 인자val1,2와 temp가 소멸됨.
  11:   


image

swap함수를 호출하면서 val1과 val2의 값을 넘겨 주었으나,
C언어에서는 두 개 이상의 변수를 반환할 수 없고,
swap( ) 내부에서 아무리 값을 바꾸어도 다른 함수의 값에는 영향을 줄 수 없다.

 

 

3. swap( ) call by reference

   1:  void swap(int *pN1, int *pN2)
   2:  {
   3:      int temp;
   4:   
   5:      temp = *pN1;
   6:      *pN1 = *pN2;    //pN1에 들어 있는 주소를 참조하여 값을 바꿈.
   7:      *pN2 = temp;    //swap을 호출한 함수의 지역변수는 값이 바뀌어짐.
   8:   
   9:      return ;    //아무것도 반환하지 않음.
  10:  }            //여기서 지역변수와 인자들이 소멸됨.
  11:   

*pN1과 *pN2에 저장된 주소값을 참조하여 직접 swap( )을 호출한 함수의 값들을 교환함.

 

4. C과제6 1번에 swap( ) 적용

   1:  void ProcessCount(int a, int b, int *pCount)
   2:  {
   3:      int temp, i;
   4:   
   5:      //a가 크면 a와 b를 교환
   6:      if(a > b)
   7:      {
   8:          temp = a;
   9:          a = b;
  10:          b = temp;
  11:      }
  12:   
  13:      //5의 배수의 갯수를 카운트
  14:      for(i = a + 1 ; i < b ; i++)
  15:      {
  16:          if(i % 5 == 0)        *pCount = *pCount + 1;
  17:      }
  18:   
  19:      return ;
  20:  }
  21:          


return문으로 반환하지 않고 *pCount에 저장된 주소로 값을 기록/읽기를 수행.

 

  일반변수 포인터변수
선언 int a; int *pA;
a *pA
주소 &a &pA
참조(주소)   pA

포인터는 특별하게 *를 앞에 붙여 자신에 저장된 값을 참조하여 그 주소에 있는 값을 읽거나 쓸 수 있다.