본문 바로가기

C언어 강좌

[C언어_13] 사용자 정의 함수, 프로토타입(Prototype)

안녕하세요,

이번 포스팅에서는 사용자 정의 함수를 알아보는 시간을 갖도록 하겠습니다.

 

함수란 일종의 작은 프로그램 단위라고 생각하시면 되는데요.

이때까지 배웠던, printf문, scanf문과 같은 것들은 C언어에서 기본으로 제공되는 함수들이었습니다.

그리고 계속 써왔던 main() 또한 함수였습니다.

 

사용자 정의 함수는 이러한 함수 외에 우리가 만들 수 있는 함수를 의미합니다.

 

 


| 함수를 만들어야 하는 이유

 

프로그램의 구현은 복잡한 문제를 해결하는 것에 비유를 할 수 있습니다.

따라서 main()이라는 하나의 함수 안에서만 문제를 해결하려 드는 것은 아무런 대책 없이 무작정 문제를 해결하려 드는 것과 마찬가지입니다. 구현하기에 앞서 어떤 기능들이 있는지 분석하고, 그 분석결과를 바탕으로 작은 크기의 함수들을 디자인해야합니다. 실제로 작은 크기의 함수를 구현하는 것은 복잡하고 커다란 문제를 작게 쪼개어 해결하는 것에 비유할 수 있습니다.

 

즉, 하나의 함수에 하나의 기능만 있도록 디자인해야합니다.

 

프로그램을 작은 크기의 함수들로 나눠서 구현하게 되면, 오류의 발생 또는 코드 변경이 필요한 경우에, 변경의 범위를 축소 및 제한할 수 있습니다. 이러한 장점은 직접 코드를 작성하고 프로그램을 실제 개발하면 와닿게 될 것입니다.


 

| 사용자 정의 함수의 구조

반환형태 + 함수이름 ( 매개변수(매개변수 자료형 + 매개변수 이름) )
{
        함수 내용
}

사용자 정의 함수의 구조는 위와 같습니다.

매개변수의 개수 또한 사용자가 필요한 만큼 정의합니다.

 

간단하게 예를 살펴보며 사용자 정의 함수가 어떤 역할을 하는지 알아보겠습니다.

 

#include <stdio.h>

int MySum(int a, int b) // 사용자 정의 함수
{
	int sum;
    	sum = a + b;
    	return sum;
}

void main()
{
	int result;
    
    	result = MySum(3, 4); // 함수 호출문
        
    	printf("%d", result);
}

위 코드를 살펴보면,

 

먼저 MySum이라는 사용자 정의 함수의 반환형태를 int형으로 선언하고, 매개변수로 int형 변수 a와 b를 사용했습니다.

MySum 함수 안에서는 매개변수인 a와 b를 sum에 저장하고, 그 값을 반환했습니다.

 

MySum 함수에서 매개변수를 2개 사용했기 때문에,

main 함수 안에서 MySum 함수를 불러들여서 사용할 때도 매개변수 2개를 정의해줘야합니다.

코드에서 result = MySum(3, 4); 처럼 말입니다.

 

즉, 함수를 정의할 때와 호출할 때의 매개변수의 개수가 같아야합니다. 물론 매개변수의 자료형 또한 같아야합니다.

 


 

| 함수 정의 위치의 중요성

 

함수의 위치를 결정할 때에도 주의를 기울여야 합니다.

이와 관련해서 앞에서 다룬 코드를 활용하여 설명하겠습니다.

 

만약 위 <A코드>를 아래 <B코드>로 바꾸게 되면 어떻게 될까요?

// <A코드>

#include <stdio.h>

int MySum(int a, int b)
{
	int sum;
    	sum = a + b;
    	return sum;
}

void main()
{
	int result;
    	result = MySum(3, 4);
    	printf("%d", result);
}

// <B코드>

#include <stdio.h>

void main()
{
	int result;
    	result = MySum(3, 4);
    	printf("%d", result);
}

int MySum(int a, int b)
{
	int sum;
    	sum = a + b;
    	return sum;
}

결과는 <B코드>는 컴파일 에러가 나게 됩니다.

 

<A코드>와 <B코드>의 차이는 바로 함수 선언의 위치입니다.

 

컴파일러는 위에서 아래로 컴파일을 진행하기 때문에,

만약 <B코드>처럼 'MySum 함수의 정의'에 앞서 'MySum 함수의 호출문'이 먼저 등장하게 되면 컴파일러는 아마도 'MySum 함수의 호출문'을 보면서 이런 불평을 할 것입니다.

 

" MySum 함수? 난 이런 함수 본적이 없는데! "

 

즉, 함수는 호출되기 전에 미리 정의되어야 합니다.


 

| 프로토타입(Prototype)이란?

 

함수가 호출되기 전에 미리 정의되어야 한다고 바로 위에서 말씀드렸습니다.

 

그렇다면 <A코드>처럼 main 함수 위에 사용자 정의 함수를 작성하면 될까요?

 

물론 그렇게 해도 되지만,

프로그램을 개발하면서 많은 사용자 정의 함수를 만들다 보면 main함수는 점점 아래로 밀릴 것입니다.

그렇게 된다면 문서를 보기 힘들어지며, 또한 함수들이 많아지면 각 함수를 찾을 때 찾기 힘들어집니다.

 

이때 필요한 것이 바로 프로토타입(Prototype)입니다.

 

바로 <B코드>를 이용해 예시를 보여드리겠습니다.

// <B코드> + 프로토타입 (Prototype)

#include <stdio.h>

int MySum(int a, int b); // 프로토타입 (Prototype)

void main()
{
	int result;
    	result = MySum(3, 4);
    	printf("%d", result);
}

int MySum(int a, int b)
{
	int sum;
    	sum = a + b;
    	return sum;
}

이렇게 main함수 보다 위에 먼저 사용자 함수를 정의할 수 있는 것이 프로토타입입니다.

 

프로토타입을 통해 main보다 위에 먼저 사용자 함수를 정의하고, 나중에 이 함수를 재선언해 내용을 넣을 수 있습니다.

 

이렇게 할 경우 위쪽엔 함수의 목록이 정리되어 매우 보기 좋을 뿐만 아니라,

함수의 내용에서 다른 사용자 함수를 호출하는데 제약이 없어집니다.

 


 

| 프로토타입(Prototype)의 구조

 

반환형태 + 함수이름 ( 매개변수(매개변수 자료형 + 매개변수 이름(생략가능)) );

프로토타입의 구조는 사용자 정의 함수의 구조와 비슷합니다.

다른 점이라면 괄호안에 함수 내용이 없고 맨뒤에 세미콜론(;)이 붙어있습니다.

 

프로토타입을 선언할 때에는,

매개변수의 이름을 두 번이나 쓸 필요가 없기 때문에 매개변수를 순서에 맞게 자료형만 적어도 됩니다. 

 

프로토타입과 사용자 함수와의 관계

  • 매개변수의 개수가 같아야합니다.
  • 매개변수의 자료형이 같아야합니다.
  • 반환형태가 같아야합니다.

이상으로 이번 포스팅 마치겠습니다.

피드백 사항이나 질문이 있으시다면 댓글 달아주시고, 공감도 한 번씩 눌러주시면 감사하겠습니다.