6-1-나.함수

사용자 정의 함수를 만드는 기본 형식은 다음과 같다.

 

type name(인수 목록)

{

          함수의 본체

}

 

name : 함수의 이름이며 이 이름을 통해 함수를 호출한다. 함수의 이름도 명칭(Identifier)이므로 명칭을 만드는 규칙대로 기억하기 쉽고 의미를 잘 표현할 수 있는 이름을 주는 것이 좋다. 점수를 출력하는 함수라면 PrintScore, 게임을 끝내는 함수라면 EndGame, 합계를 구하는 함수라면 GetSum 같은 이름을 붙이면 된다.

인수 목록 : 함수가 해야 할 일의 세부 사항을 지정하며 함수의 작업거리라고 할 수 있다. 함수는 고유의 기능을 가지고 있고 호출부에서는 이 기능을 사용하기 위해 함수를 호출하는데 이때 함수에게 일을 시키기 위해서는 작업에 필요한 값을 전달해야 한다. 함수의 동작에 필요한 인수는 없을 수도 있고 여러 개일 수도 있는데 인수 목록에 필요한 인수의 타입과 이름을 밝힌다.

예를 들어 점수를 화면으로 출력하는 PrintScore 함수의 경우 출력할 현재 점수가 몇점인가를 가르쳐 주어야 하며 이런 정보가 인수로 전달된다. 만약 점수값 하나만 인수로 전달받는다면 PrintScore(int Score) 식으로 점수를 전달받을 것이다. printf는 서식 문자열과 출력할 값을 인수로 전달받으며 gotoxy는 이동 좌표를, delay는 지연시간을 전달받는다. 인수는 필요한만큼 사용할 수 있으며 개수의 제한은 없다. 필요하다면 점수를 출력할 좌표나 점수의 출력 형태 등도 인수로 전달받을 수 있다.

type : 함수가 리턴하는 값의 데이터형이며 함수의 작업 결과라고 할 수 있다. 함수는 고유의 작업을 실행하고 그 결과를 호출원에게 다시 돌려 준다. 예를 들어 합계를 구하는 함수 GetSum은 자신이 구한 합계를 호출원에게 보고하는데 이때 돌려주는 값의 타입이 바로 함수의 타입이다. 정수형 값을 리턴한다면 int, 실수형 값을 리턴한다면 double이라고 타입을 써 준다. getch 함수는 입력된 문자값을 리턴하며 wherex, wherey는 커서 좌표를 조사한다. 단순히 어떤 기능만 수행하는 함수라면 리턴하는 값이 없을 수도 있는데 이런 함수를 void 함수라고 한다.

본체 : { } 괄호안에 실제 함수의 코드가 위치한다. 이 블록 안에 함수의 고유 기능을 수행하는 코드를 작성하면 된다. PrintScore 함수의 본체에는 인수로 전달된 점수값을 printf 함수로 출력하는 코드가 작성될 것이다.

 

다음 예제는 사용자로부터 두 개의 정수값을 입력받아 그 중 큰 값을 출력한다. 값의 크기 비교는 >나 < 연산자로 간단하게 할 수 있지만 함수의 사용예를 보이기 위해 Max라는 사용자 정의 함수를 만들었다.

 

: MaxFunc

#include <Turboc.h>

 

int Max(int a, int b)

{

     if (a > b) {

          return a;

     } else {

          return b;

     }

}

 

void main()

{

     int a,b,m;

 

     printf("두 수를 입력하세요 : ");

     scanf("%d%d",&a,&b);

     m=Max(a,b);

     printf("두 수 중 큰 값은 %d입니다.\n",m);

}

 

소스에는 main 함수 외에도 Max라는 사용자 정의 함수가 정의되어 있다. 실행 결과는 다음과 같다.

 

두 수를 입력하세요 : 5 8

두 수 중 큰 값은 8입니다.

 

scanf로 두 개의 정수값을 입력받아 a, b 변수에 저장했는데 5와 8을 입력했다면 a는 5가 되고 b는 8이 될 것이다. 이 두 값을 Max 함수의 인수로 전달하면 Max는 두 값 중 큰 값을 골라 다시 리턴한다. 함수가 실행을 마치고 값을 돌려줄 때는 return 키워드를 사용하는데 이 명령에 대해서는 잠시 후 따로 알아볼 것이다. 이 경우는 5보다 8이 크므로 8이 리턴된다.

프로그램은 항상 main 함수에서 시작한다. main에서 사용자로부터 두 개의 정수 a와 b를 입력받았다. 그리고 이 두 값 중에서 큰 값을 가려내기 위해 Max 함수를 호출하며 이때 Max 함수로 작업 대상이 되는 두 개의 값 a와 b가 인수로 전달된다.

함수를 호출할 때는 "함수명(인수)"의 형식을 사용하는데 함수 이름과 괄호 그리고 괄호안에 인수들을 같이 전달해야 한다. main에서 Max(a,b)라는 형식으로 Max 함수를 호출했다. 인수가 없는 함수의 경우는 Max() 식으로 함수 이름 뒤에 빈 괄호만 써 준다. 설사 인수가 없다 하더라도 괄호는 생략할 수 없는데 C는 명칭 뒤에 괄호가 있어야 함수 호출문으로 인식하며 괄호가 없으면 함수의 시작 번지를 나타내는 포인터 상수가 되어 버린다.

Max 함수는 호출원인 main으로부터 두 개의 정수값 a, b를 인수로 전달받아 이 두 값을 비교해 보고 큰 값을 리턴한다. a가 b보다 더 크다면 a를 리턴하고 그렇지 않다면 b가 리턴될 것이다. 만약 두 값이 같다면 b를 리턴하도록 되어 있는데 어떤 값을 리턴하나 결과는 마찬가지이다. Max 함수는 두 정수값중 큰 정수를 골라 다시 리턴하므로 함수의 리턴 타입은 역시 int형이다. int Max(int a, int b)는 정수형 변수 a, b를 인수로 받고 다시 정수값을 리턴하는 Max라는 이름의 함수라는 뜻이다.

Max 함수에 의해 리턴되는 정수값은 정수형 변수 m에 대입되며 main 함수는 이 값을 출력한 후 종료된다. 이 프로그램의 전체적인 흐름은 다음과 같다.

Max 함수는 인수로 전달된 두 값 중 큰 값을 가려내는 함수로 정의되어 있고 main은 두 정수중 큰 값을 조사하기 위해 단순히 인수와 함께 Max 함수를 호출하기만 하면 된다. main은 큰 값을 가려내는 일에는 신경쓸 필요가 없으며 Max는 무조건 인수로 전달된 값 중 큰 값을 골라 리턴하기만 하면 맡은 바의 소임을 다하는 것이다. Max가 main의 부담을 덜어주는 역할을 하고 있다.

물론 이런 짧은 코드의 경우 main에서 직접 if (a > b) 조건을 점검할 수도 있다. 그러나 함수의 내용이 커지고 계산 과정이 복잡해지면 main에서 모든 일을 다 처리하기가 어려워지고 설사 그렇게 할 수 있다 하더라도 코드의 길이가 길어지면 어디서 어디까지가 어떤 기능을 하는 부분인지 명확하게 구분되지 않기 때문에 논리적으로 취약한 구조가 되어 버린다.

함수별로 특정 기능을 담당하도록 프로그램의 기능을 분할해 놓으면 코드의 구조가 만들어지기 때문에 관리하고 재사용하기 편리하다. C언어를 구조적 프로그래밍(Structural Programming) 언어라고 하는 이유가 바로 여기에 있다. 또한 비슷한 작업을 반복적으로 계속 수행할 때는 전담 함수를 만들어 놓고 필요할 때마다 이 함수만 호출하면 되므로 코드의 반복을 방지할 수도 있다. 그래서 함수를 프로그램의 부품이라고 하는 것이다.