C 언어로 재귀와 반복문을 사용한 피라미드 그리기
C 언어에서 반복문과 재귀를 활용하여 피라미드를 그리는 방법에 대해 알아보자. 반복문과 재귀가 어떻게 작동하는지 살펴보고, #을 출력하여 피라미드를 그리는 과정에 대해 깊이 이해해보고자 한다.
반복문을 사용한 피라미드 그리기
먼저 반복문을 사용해서 피라미드를 그리는 방법을 살펴보자.
코드 예시 (반복문 사용)
#include <cs50.h>
#include <stdio.h>
void draw(int h);
int main(void)
{
// 사용자로부터 피라미드의 높이를 입력 받아 저장
int height = get_int("Height: ");
// 피라미드 그리기
draw(height);
}
void draw(int h)
{
// 높이가 h인 피라미드 그리기
for (int i = 1; i <= h; i++)
{
for (int j = 1; j <= i; j++)
{
printf("#");
}
printf("\n");
}
}
반복문을 사용한 설명
- for (int i = 1; i <= h; i++):
이 외부 반복문은 피라미드를 그릴 높이만큼 반복한다. i가 1부터 h까지 증가하면서, 각 줄에 출력할 #의 개수가 결정된다. - 내부 반복문 for (int j = 1; j <= i; j++):
- i의 값에 따라, #을 몇 개 출력할지를 결정하는 내부 반복문이다.
- i = 1일 때는 j가 1번 반복되어 #이 1개 출력된다.
- i = 2일 때는 j가 2번 반복되어 #이 2개 출력된다.
- 이렇게 반복문이 진행되면서 i가 1부터 h까지 증가할 때마다 #이 한 줄에 하나씩 추가되어 출력된다.
동작 과정 (예시: height = 4일 경우)
#
##
###
####
- i = 1: j는 1번 반복, # 1개 출력
- i = 2: j는 2번 반복, # 2개 출력
- i = 3: j는 3번 반복, # 3개 출력
- i = 4: j는 4번 반복, # 4개 출력
각각의 i 값에 따라 #이 점차 늘어나면서, 피라미드 모양의 결과가 출력된다.
재귀를 사용한 피라미드 그리기
이번에는 재귀를 사용하여 피라미드를 그리는 방법을 살펴보자. 재귀를 사용하면 반복문을 사용할 필요 없이, 함수가 자기 자신을 호출하면서 동일한 작업을 반복하게 된다.
코드 예시 (재귀 사용)
#include <cs50.h>
#include <stdio.h>
void draw(int h);
int main(void)
{
// 사용자로부터 피라미드의 높이를 입력 받아 저장
int height = get_int("Height: ");
// 피라미드 그리기
draw(height);
}
void draw(int h)
{
// 높이가 0이라면 그릴 필요가 없으므로 종료
if (h == 0)
{
return;
}
// 높이가 h-1인 피라미드 그리기
draw(h - 1);
// 피라미드에서 폭이 h인 한 층 그리기
for (int i = 0; i < h; i++)
{
printf("#");
}
printf("\n");
}
재귀의 동작 원리
- draw(h) 함수:
draw 함수는 피라미드를 그리기 위해 재귀적으로 자신을 호출한다. 이 함수는 h라는 높이를 받아서, 그 높이에 해당하는 만큼 #을 출력한다. - if (h == 0):
재귀 호출의 종료 조건이다. h가 0이 되면 더 이상 출력을 하지 않기 위해 함수가 종료된다. 즉, 더 이상 피라미드를 그리지 않도록 하는 역할을 한다. - draw(h - 1):
이 줄이 재귀의 핵심이다. h가 1씩 줄어들면서, draw 함수가 계속 자기 자신을 호출한다. 이를 통해 한 층씩 그려지는 방식이다. - 한 층 그리기:
draw(h)에서 for (int i = 0; i < h; i++) 반복문은 h번 반복되면서 #을 출력한다. h가 1씩 줄어들면서 피라미드를 거꾸로 그린 후, 다시 올라가면서 차례대로 출력을 시작한다.
동작 과정 (예시: height = 4일 경우)
- draw(4) 호출
사용자가 높이 4를 입력하면 draw(4)가 호출된다. 그런데 draw(4)는 먼저 draw(3)을 호출한다. 그런 다음, draw(3)은 draw(2)를, draw(2)는 draw(1)을, draw(1)은 draw(0)을 호출하는 것이다. - draw(0)에서 종료
draw(0)이 호출되면, if (h == 0) 조건이 참이 되어 바로 return된다. 즉, 더 이상 아래 코드를 실행하지 않고 함수가 종료! 그때부터 각 draw(n) 함수들이 다시 돌아가면서 출력을 시작함. - draw(1)부터 출력 시작
draw(0)에서 반환된 후, draw(1)부터 차례대로 실행된다. draw(1)에서는 for 반복문을 통해 #을 한 번 출력하는 것이다. - draw(2)에서 출력
그 다음 draw(2)로 돌아가면, for 반복문이 실행되어 #이 두 번 출력된다. - draw(3)과 draw(4)에서도 출력
마찬가지로, draw(3)은 세 번, draw(4)는 네 번의 #을 출력하면서 피라미드 모양을 완성한다.
결과
#
##
###
####
반복문과 재귀의 차이점
- 반복문: 반복문은 지정된 횟수만큼 코드를 반복 실행하는 구조로, 루프가 끝날 때까지 계속해서 같은 작업을 반복한다.
- 재귀: 재귀는 함수가 자기 자신을 호출하면서 반복 작업을 수행한다. 종료 조건이 없다면 무한히 반복될 수 있지만, 종료 조건을 잘 설정하면 효율적으로 반복 작업을 할 수 있다.
언제 반복문을 사용할까?
- 반복문은 코드가 간단하고, 반복 횟수가 명확할 때 유용하다. 예를 들어, #을 반복해서 출력할 때처럼.
언제 재귀를 사용할까?
반복문을 사용하지 않고 재귀를 사용하는 이유는 두 가지로 볼 수 있다.
- 함수의 호출 구조로 문제를 해결
재귀를 사용하면 문제를 작은 부분으로 나눠서 해결할 수 있다. draw(h) 함수에서 h가 0에 이를 때까지 자기 자신을 호출하고, 마지막에 도달하면 출력이 시작된다. - 코드의 간결성
재귀를 사용하면 반복문을 사용할 때보다 코드가 더 간결해지고, 각 함수 호출의 실행 흐름을 직관적으로 파악할 수 있다.
재귀는 반복문을 대체할 수 있는 강력한 도구다. 그러나 재귀를 사용할 때는 종료 조건을 명확하게 설정해주어야 한다. 그렇지 않으면 무한 재귀가 발생하여 프로그램이 종료되지 않거나 예상하지 못한 결과를 초래할 수 있다. 재귀는 반복문과 다르게 함수가 자신을 호출하면서 문제를 풀어가는 방식이므로, 코드의 흐름을 잘 이해하고 활용해야 한다.
재귀를 이해하고 활용하는 것이 처음에는 어려울 수 있지만, 반복문을 대체할 수 있는 중요한 기법이므로 계속해서 연습하고 익숙해지고 싶다 🥰. 나중에 더 복잡한 문제를 풀 때에도 이 원리를 활용할 수 있을테니까.
반응형
'IT' 카테고리의 다른 글
C 프로그래밍에서 16진수와 메모리 주소 이해하기: 포인터와 역참조까지 (0) | 2025.03.27 |
---|---|
병합 정렬(Merge Sort) : 효율적인 정렬 알고리즘 배우기 (0) | 2025.03.25 |
정렬 알고리즘 완벽 이해: Big O와 Big Ω로 실행 시간 최적화하기(: (0) | 2025.03.24 |
선택 정렬 완벽 이해: 장점, 단점 및 성능 비교 | O(n²) 알고리즘 (0) | 2025.03.24 |
인스타그램 성장을 위한 5가지 AI 도구 비교 | 유료 vs 무료, 가격과 특징 정리 (0) | 2025.03.24 |
댓글
이 글 공유하기
다른 글
-
C 프로그래밍에서 16진수와 메모리 주소 이해하기: 포인터와 역참조까지
C 프로그래밍에서 16진수와 메모리 주소 이해하기: 포인터와 역참조까지
2025.03.27 -
병합 정렬(Merge Sort) : 효율적인 정렬 알고리즘 배우기
병합 정렬(Merge Sort) : 효율적인 정렬 알고리즘 배우기
2025.03.25 -
정렬 알고리즘 완벽 이해: Big O와 Big Ω로 실행 시간 최적화하기(:
정렬 알고리즘 완벽 이해: Big O와 Big Ω로 실행 시간 최적화하기(:
2025.03.24 -
선택 정렬 완벽 이해: 장점, 단점 및 성능 비교 | O(n²) 알고리즘
선택 정렬 완벽 이해: 장점, 단점 및 성능 비교 | O(n²) 알고리즘
2025.03.24