C언어/C언어 3차시

3차시 함수, 재귀함수

sjong 2023. 4. 14. 23:57

함수

프로그래밍에서 함수란 특별한 목적의 작업을 수행하기 위해 독립적으로 설계된 프로그램 코드의 집합으로 정의할 수 있습니다.

C 프로그램은 이러한 함수들로 구성되며, 포함된 함수들을 사용하여 목적을 달성하게 됩니다.

함수를 사용하는 이유는 반복적인 프로그래밍을 피하기 위함이며, 필요할 때마다 함수를 호출하여 반복작업을 실행할 수 있습니다. 

 

함수를 선언하는 방법은 다음과 같습니다.

 

변환자료형 함수이름 (매개변수 목록)

{

    함수 내용;

}

 

이를 코드로 짜면 다음과 같습니다.

#include <stdio.h>

int func(int a){
  if(a>5)
    printf("%d는(은) 5보다 큽니다",a);
  else if(a<=5)
    printf("%d는(은) 5보다 작거나 같습니다",a);
  return 0;
}

func라는 함수를 int형으로 선언하였습니다.

그 안에 매개변수 a라는 값을 선언 후 a가 5보다 크면 조건이 참이 되고 조건 아래의 코드를 실행합니다

그러나 만약 a가 5보다 작거나 같으면 그 조건에 해당하는 코드를 실행합니다.

마지막에는 return  0;을 두어 함수가 끝남을 말합니다. 

 

이 함수를 사용한 프로그램은 다음과 같습니다.

 

#include <stdio.h>

int func(int a){
  if(a>5)
    printf("%d는(은) 5보다 큽니다",a);
  else if(a<=5)
    printf("%d는(은) 5보다 작거나 같습니다",a);
  return 0;
}

int main(){
  int n;
  scanf("%d",&n);
  func(n);
  return 0;
}

main 함수에서 n의 값을 입력받습니다.

그리고 함수이름(매개변수에 넣을 값)을 작성하여 func 함수의 a 값에 n을 넣습니다.

이렇게 되면 func의 a는 n이 된 상태로 함수 안의 코드들을 실행합니다.

 

실행결과는 다음과 같습니다.

>10
10는(은) 5보다 큽니다
>3
3는(은) 5보다 작거나 같습니다

이처럼 a의 값에 입력받은 n의 값이 들어가 정상적으로 실행되는 것을 볼 수 있습니다.


재귀함수

재귀함수란 함수 내부에서 함수가 자기 자신을 또다시 호출하여 실행하는 행위를 의미합니다.

이러한 재귀함수는 자기가 자신을 계속해서 호출하므로, 끝없이 반복되게 됩니다.

따라서 함수 내에 재귀호출을 중단하도록 하는 조건 명령문을 반드시 포함해야 합니다.

 

함수를 알아보기 위해 1부터 n까지의 합을 구하는 프로그램을 보겠습니다.

 

먼저 함수 안에 for문을 넣어 출력한 코드는 다음과 같습니다.

#include <stdio.h>

int sum(int n){
  int i,result=0;
  for(i=1;i<=n;i++)
    result+=i;
  return result;
}

이는 일반적인 함수의 코드입니다.

sum이라는 int형 함수안에 매개변수 n을 선언합니다. 

함수 안에는 i와 result라는 새로운 변수를 정의합니다.

그다음 for반복문을 통해 result 변수에 i의 값을 더해 1부터 n까지의 모든 수를 더합니다.

마지막에는 result 값을 반환합니다. 

 

만약 코드를 이렇게 짜면 i와 result의 값이 왜 선언되었는지 바로 알 수 없으며, 함수의 목적을 바로 파악하기 힘듭니다.

 

재귀함수를 만들기 전에 먼저 의사코드를 보겠습니다.

시작

    n이 1이 아니면, 1부터 (n-1)까지의 합에 n을(를) 더한 값을 반환한다.
	n이 1이면, 그냥 1을 반환한다.

끝

예를 들어 입력값 n이 5면 1부터 4까지의 합에 5를 더한 값을 반환하고, n이 1이면 그냥 1이 반환됩니다. 

만약 n이 1일 때 1을 반환하지 않으면 스택 오버플로우에 의해 프로그램은 종료될 것입니다.

 

이 알고리즘을 재귀함수 코드로 짜면 다음과 같습니다.

#include <stdio.h>

int sum(int n){
    if (n==1) 
          return 1;
    return n + sum(n-1);
}

먼저 만약 n이 1이라면 1이라는 값을 반환해 줍니다.

그리고 n의 값과 sum(n-1) 함수의 반환값을 더하고 그 값을 반환합니다.

이를 위해선 sum(n-1)을 먼저 실행합니다.

 

예를 들어 n의 값이 3이라고 해보면

3의 값과 sum(2) 함수의 반환값을 더하고 그 값을 반환합니다.

이를 위해선 sum(2)를 먼저 실행합니다. 

sum(2)에선 2의 값과 sum(1) 함수의 반환값을 더하고 그 값을 반환합니다.

이를 위해선 sum(1)을 먼저 실행합니다.

이때 n의 값이 1이므로 1을 반환합니다.

이렇게 되면 1+2+3이 되어 최종적으로 sum(3)의 함수는 6을 반환합니다.

 

이 함수를 사용한 프로그램은 다음과 같습니다.

#include <stdio.h>

int sum(int n){
    if (n==1) 
          return 1;
    return n + sum(n-1);
}

int main(){
  int n;
  scanf("%d",&n);
  printf("%d",sum(n));
  return 0;
}

n의 값을 입력받고 그 n을 함수의 매개변수 n에 저장한 상태로 코드를 실행합니다.

 

실행 결과는 다음과 같습니다. 

>3
6

보기엔 복잡해 보여도 재귀호출을 이해하면 쉽게 느껴질 것입니다.

예를 들어 '화면 안에 화면 안에 화면 안에 오렌지'가 있습니다.
그러면 먼저 '오렌지'를 보여줍니다.
그다음은 '화면 안에 있는 오렌지'를 보여줍니다.
다음으로 '화면 안에 화면 안에 있는 오렌지'를 보여줍니다.
마지막으로 '화면 안에 화면 안에 화면 안에 있는 오렌지'를 보여줍니다.
결론적으로 우리의 눈은 이 모든 것들을 한눈에 보게 됩니다.
이를 코드로 보면 우리의 눈은 실행 결과가 되고 그 과정이 재귀 함수가 됩니다.

이처럼 재귀함수를 이용하면 직관적으로 프로그램을 짤 수 있습니다.
하지만 재귀함수는 비재귀함수보다 실행 시간이 오래 걸리는 단점 또한 있기에 상황에 알맞게 사용해야 합니다.