[Algorithm] 정수를 문자열로 출력하기

Heechul Yoon·2022년 4월 9일
0

문자열 출력 함수에서 어떻게 매개변수로 넣은 정수형을 곧바로 문자열로 포매팅해서 출력할까?
아스키테이블에는 0~9까지의 숫자표현만 존재한다. 만약 2147483647라는 정수를 출력하기 위해서는 각자리당 문자 하나씩해서 출력해야한다.

fprintf("%d", 2147483647);

위의 코드를 실행하면 함수안에서 매개변수로 받은 정수를 마법같이 문자열로 바꿔서 표준출력에 보여준다.

> 2147483647% 

문자열 출력함수가변 길이 매개변수에 대해서는 다른 포스팅에서 알아보도록 하고,
이번에는 정수형 데이터를 문자열로 출력하는 방법중 재귀함수의 호출스택을 사용하는 방법을 알아보겠다.

static void print_int_reculsive(int i)
{
    if (i == 0) { /* 3. */ 
        return;
    }

    print_int_reculsive(i / 10); /* 4. */ 
    putchar('0' + i % 10); /* 5. */ 
}

static void print_int(int i)
{
    if (i == 0) {
        putchar('0'); /* 1. */ 
    }

    print_int_reculsive(i); /* 2. */ 
}

int main(void)
{
    print_int(__INT_MAX__);
}

1. i가 0인경우

우선 매개변수로 들어온 정수가 0의 경우를 따로 처리해주지 않으면 2번을 거쳐 3번으로 빠지게 될텐데 이렇게되면 문자열을 출력할수가 없기 때문에 우선 매개변수가 0인경우는 그냥 0을 출력해주도록 하자

2. 재귀함수 호출

이제 재귀함수를 호출해서 i를 아스키테이블상의 1~9의 문자로 바꿔서 char 하나를 출력하도록 한다

3. 재귀함수 종료 조건

재귀함수에 의해서 i는 계속 10으로 나눈 몫으로 들어올것이다. 만약 i0이되면, 즉, 10으로 나눈 몫이 0으 되면 모든 정수에서 모든 자리의 평가가 끝났음을 의미하기 때문에 재귀호출을 끊어준다

4. 재귀함수 호출

실제로 현재 자리에 있는 문자를 출력하기 전에 정수에 있는 앞의 모든 숫자들을 먼저 출력해야한다.
예를들어 2147483647 라는 정수가 있다면 7을 출력하기전 4를출력해야하고 4를출력하기전 6을 출력해야하고 ... 1을출력하기전 2를 출력해야한다. 2는 정수중에서 가장 앞자리에 속하기 때문에 2를 출력하는 호출스택에서 print_int_reculsive(0)의 함수의 매개변수로 0을 넘겨주게 되어서 재귀호출이 종료된다.

5. 각 자리 출력

이제 재귀함수의 호출스택이 2를 출력하는 단계까지 왔다면 2부터 1, 4, 7, 4, 8, 3 순으로 7까지 출력을하고 호출스택이 전부 pop되면 함수가 리턴된다.
여기서 putchar('0' + i % 10); 아스키 문자 0에 아스키테이블에서의 오프셋만큼 값을 더해주면 0~9까지 범위안에서 자유롭게 출력이 가능하다.

각 호출스택마다 라인브레이크를 넣어주면 아래와같이 출력된다

스택을 사용한다면 재귀함수를 상용하지 않아도 구현할 수 있을 것 같다.

profile
Quit talking, Begin doing

0개의 댓글