고감자님의 "printf를 쓰지 않고 숫자 출력하기."에 대한 트랙백
- 가장 얍실한 방법입니다. sprintf로 변환한 다음 출력하는 것이죠.
너무 출제자의 의도를 왜곡한 것일까요?
하지만 가장 똑똑한 방법이기도 합니다.
주어진 제약 사항 안에서는 가장 완벽하고 쉽기 때문이죠.
void pn0(int num)
{
char buf[80];
sprintf(buf, "%d", num);
puts(buf);
}
- sprintf에도 printf라는 글자가 있으니 조금 덜 미안하게 itoa를 통해서 변환하는 방법입니다.
뭐 일번과 별 차이는 없죠. 단지 눈에서 printf가 완전히 없어졌다는 차이가 있을 뿐입니다.
void pn1(int num)
{
char buf[80];
itoa(num, buf, 10);
puts(buf);
}
- 이제 좀 출제자의 의도대로 풀어봅시다.
결국 숫자를 출력하는데 가장 중요한 기본적인 아이디어는 진수(?), 배수(?)로 나누는 것입니다.
십진수니까 십으로 나누면 분해가 되죠. 남은 숫자는 십으로 나눈 나머지를 출력하면 됩니다.
do
{
putchar((num%10) + '0');
} while(num/=10);
이렇게 짤 때 단순히 반복문으로 작성하면 위와 같습니다.
출력해 보면 아시겠지만 역순으로 출력돼죠.
그래서 그걸 다시 원래 순서로 돌리기 위해서는 스택 내지는 그에 상응하는 장치가 필요합니다.
그런 장치로 재귀 호출을 사용한 버전이 아래 코드입니다.
재귀호출 스택 프레임이 스택과 같은 구조로 쌓였다가 풀리기 때문에 스택과 동등한 역할을 합니다.
void pn2(int num)
{
if(num < 10)
{
putchar(num + '0');
return;
}
pn2(num / 10);
pn2(num % 10);
}
이것은 단지 트릭입니다!!!
재귀호출을 사용해야 하는 가장 이상적인 곳은 문제의 정의 자체가 재귀인 경우입니다.
이 경우에는 문제가 자체가 직접적인 재귀 구조는 아니죠.
따라서 재귀호출을 사용하는 것이 좋은 방법은 아닙니다.
- 마지막 방법은 고감자님의 방법과 같습니다.
자리수를 구해서 나누면서 하나씩 출력하는 것이죠.
void pn3(int num)
{
int p = 10;
while(num / p)
p \*= 10;
do
{
p /= 10;
putchar((num/p) + '0');
} while(num%=p);
}