Home C언어 공부 정리(3/10)-연습문제
Post
Cancel

C언어 공부 정리(3/10)-연습문제

22/01/03

1. 16진법을 10진수로 출력하는 프로그램

(22/01/06 추가)

  • ex) 42C(입력) → 1068(출력)
  • 조건
    • getchar() 사용(입력)
    • 입력 끝은 ‘\n’
    • 단순변수로 해결할 것
    • 한 자리씩 10진수로 변환 후 누적된 결과로 출력
    • 출력 : printf();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>

// exit() 사용
#include <stdlb.h> 

int main() {

  // 변수 선언

  while ((c=getchar()) !='\n') {
    if (c >= '0' && c<='9')
      
      // 숫자 변환
    
    else if(c>='A' && c<='F')

      // 슷지 변환
    
    else {
      printf("16진수가 아닙니다\n");
      exit(1); // 강제 종료
    }

    // 누적된 결과 저장

  }
  printf("%d\n", value);

  return 0;
}



소스 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <stdlb.h> 

int main() {

  char c; // 문자 입력 받을 변수
  int num; // char를 int로 변경하기 위한 변수
  int value = 0;

  // getchar()가 \n이 아닐 동안 계속 반복
  while ((c=getchar()) !='\n') {
    if (c >= '0' && c<='9')
      
      num = c - '0'; // 1. c = ascii code, 묵시적 형변환
    
    else if(c>='A' && c<='F')

      num = c - 'A' + 10;
    
    else {
      printf("16진수가 아닙니다\n");
      exit(1); // 강제 종료
    }

    // 2. 16진법 -> 10진법 변경
    value = value * 16 + num;

  }
  printf("%d\n", value);

  return 0;
}

+ getchar() : 한 문자만 받는다.
+ scanf(“포맷”, 변수주소) : 문자 또는 문자열을 받는다.

  1. 16진수 : 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
    • A : 10진수의 10
    • F : 10진수의 15
  2. char = 1문자, ascii code를 사용
    • ascii code = 0 ~ 127까지의 번호로 저장되어 있는 문자코드
    • ‘0’입력 시 >> num = 48(0의 ascii code) - 48 >> num = 0;
    • ‘5’입력 시 >> num = 53 - 48 >> num = 5;
    • ‘D’입력 시 >> num = 69 - 65 + 10 >> num = 14;
  3. 10진법과 16진법
    • 10진법의 숫자 : 0,1,2,3,4,5,6,7,8,9
    • 16진법의 숫자 : 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
    • 3825(10) → 3 x 1000 + 8 x 100 + 2 x 10 + 5 x 1(100)
      • 이전 자리수에 비해 다음 자리수는 10배 커진다. ( value * 10 )
      • 이전 숫자 + 다음 숫자 >> value * 10 + num(이전 숫자)
      • 0 x 10 + 3 >> 3 x 10 + 8 >> 38 x 10 + 2 >> 382 x 10 + 5 >> 3825
    • 16진법의 10진법 변환법
      • 12A(16) → 1 x 162 + 2 x 161 + 10 x 160 → 298(10)
    • 16진법을 10진법으로 변환하기 위해 16을 곱하고 다음 숫자를 더함 ( value * 16 + num)

실행순서

  • (예시)12C입력
  • ‘1’ > 1
  • value = 0 * 16 + 1 >> value = 1
  • ‘2’ > 2
  • value = 1 * 16 + 2 >> value = 18
  • ‘C’ > 12
  • value = 18 * 16 + 12 >> value = 300
  • 결과 : 300

2. 10진수를 2진수로 출력하는 프로그램

  • ex)
    • 10(입력) → 00000000000000000000000000001010 (출력)
    • -10(입력) → 11111111111111111111111111110110 (출력)
  • 조건
    • scanf() 사용(입력)
    • 비트 연산자 이용
    • 한 비트씩 체크 결과 0이면 putchar(‘0’) or printf(“0”), 1이면 putchar(‘1’) or printf(“1”)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
include <stdio.h>

int main() {

    // 변수선언

    scanf("%d". &num);

    for (i=0; i<32; i++) {

        // num의 한 비트씩 체크해 0 또는 1 출력

    }
    return 0;
}



소스 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
include <stdio.h>

int main() {

    int num; // 숫자 입력받을 변수
    int i; // for문 변수

    // 1. 비트 체크를 위한 변수
    unsigned int check = 0x80000000; // 1000...0000

    // 2. scanf("포맷", 변수 주소);
    scanf("%d", &num); 

    // 3. int = 32 bit
    for (i=0; i<32; i++) {
        if((num&check) == 0) // 숫자와 check 확인결과 0일 경우
            putchar('0');
        else                 // 숫자와 check 확인결과 1일 경우
            putchar('1');

        // 4. 다음 비트를 확인하기 위한 shift
        check = check >> 1;
    }
    putchar('\n');
    return 0;
}
  1. 프로그램에서 출력되는 숫자는 10진법이지만 컴퓨터는 2진법으로 인식
    • 1(출력) : 00000000000000000000000000000001(인식)
    • 왼쪽에서부터 한 비트씩 (0 or 1)을 출력하기 위한 변수
    • *unsigned : 음수가 없는 정수
  2. 데이터를 입력받을 수 있는 함수
    • 변수의 주소로 값을 가져올 수 있다.
    • &변수 : 변수의 주소값
  3. 입력받은 정수를 한 비트씩 이진법으로 출력하기 위해 for문으로 32번 반복
  4. 다음 비트를 확인하기 위한 shift
    • >> : 비트가 오른쪽으로 이동
    • ex) 0110 >> 2 → 0001
    • check를 일반 정수 데이터로 선언 시, 첫 비트가 1이므로 음수 로 인식
      • 양수의 >> : 빈 공간은 0으로 채워짐
      • 음수의 >> : 빈 공간은 1로 채워짐(음수인 것을 유지해야 함으로)
    • >>연산자 사용 시 0이 오게끔 하기 위해 음수가 없는 *unsigned로 선언

실행 순서

  • (예시)15 입력
  •     0000 00…00 1111 (15)
    & 1000 00…00 0000 (check)
    ------------------------------
        F
  • check >> 1 (1비트 이동)
  •     0000 00…00 1111 (15)
    & 0100 00…00 0000 (check)
    ------------------------------
            F
  • check >> 1
  •     0000 00…00 1111 (15)
    & 0010 00…00 0000 (check)
    ------------------------------
              F

                            …

  • check >> 1
  •     0000 00…00 1111 (15)
    & 0000 00…00 1000 (check)
    ------------------------------
                                T

  • 결과
    • 00000000000000000000000000001111

3. left circular shift 프로그램

  • left circular shift : 주어진 정수의 비트를 왼쪽으로 n번 이동
  • ex)
    • 10 3(입력) → 00000000000000000000000000001010 (원본)
                               00000000000000000000000001010000 (결과)
    • -10 3(입력) → 11111111111111111111111111110110 (출력)
                                 11111111111111111111111110110111 (결과)
  • 조건
    • scanf() 사용
    • 입력된 데이터의 원본과 결과물 모두 2진수로 출력
    • 왼쪽으로 이동 시 비트가 0이면 0추가, 1이면 1추가
      • ex) 1011 0000 « 3 → 1000 0101
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>

int main() {

  // 변수 선언

  scanf("%d %d", &num, &n);
  
  // 입력된 원본 2진수 출력
  
  for (i=0; i<n;i++) {

    // left circular shift

  }

  // shift 결과 출력

  return 0;
}



소스 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdio.h>

int main() {

  int num;
  int n;
  int i;
  unsigned int check = 0x80000000;

  scanf("%d %d", &num, &n);
  
  // 원본 2진수 출력
  for (i=0; i<32; i++) {
        if((num&check) == 0)
            putchar('0');
        else
            putchar('1');
        check = check >> 1;
    }
    putchar('\n');
  
  // 위에서 check가 shift로 인해 0이 되었으므로 다시 값 선언
  check = 0x80000000;

  // 1. left circular shift
  for (i=0; i< n;i++) {
    // 2. check 결과 0이면 shift
    if ((num&check)==0) {
        num = num << 1;
    }
    // 3. check 결과 1이면 shift 후 1 추가
    else {
      num = num << 1;
      num |= 1;
    }
  }

  // shift 결과 출력
  for (i=0; i<32; i++) {
        if((num&check) == 0)
            putchar('0');
        else
            putchar('1');
        check = check >> 1;
    }

  return 0;
}
  1. n번만큼 왼쪽으로 이동하기 위해 조건을 i<n으로 설정
  2. << 실행 시 비어있는 공간은 자동으로 0으로 채워짐
    • ex) 0010 « 1 → 0100
    • num과 check 결과 0이면 다른 실행문 없이 shift만 사용
  3. num과 check 결과 1이면 0이 아닌 1을 추가해야 함으로 1이라는 정보 추가
    • int x = 8 → 1000
    • x |= 1 → 1000 + 0001 = 1001

실행순서

  • -15 4 입력
  •     1111 11…1111 0001
    & 1000 00…0000 0000 (check)
    ---------------------------------
        T
  • num « 1 (1비트 이동)
  •     1111 11…1110 0011
    & 1000 00…0000 0000 (check)
    ---------------------------------
        T
  • num « 1
  •     1111 11…1100 0111
    & 1000 00…0000 0000 (check)
    ---------------------------------
        T
  • num « 1
  •     1111 11…1000 1111
    & 1000 00…0000 0000 (check)
    ---------------------------------
        T
  • num « 1

  • 결과
    • 11111111111111111111111111110001
      11111111111111111111111100011111
This post is licensed under CC BY 4.0 by the author.

C언어 공부 정리(2/10)-제어문

C언어 공부 정리(4/10)-함수

Comments powered by Disqus.