C언어에서 가장 중요한 부분의 하나는 바로 함수입니다. 기 정의된 표준 함수의 사용법을 잘 알고 사용하는 것 뿐만 아니라 스스로 함수를 만드는 것도 중요합니다. 함수는 C 프로그램의 시작과 끝이라고 해도 관언이 아닙니다. 이번에는 함수에 대해서 알아보도록 하겠습니다.

 

함수(Function)

C언어에서 가장 중요한 역할은 함수(function)입니다. 이 함수는 수학에서 말하는 함수와 비슷한 면이 있습니다.

 

수학에서는

f(x) = 6x + 9

처럼 함수를 정의하고, f(3) = 27 처럼 결과 값을 얻습니다.

 

C언어도 표현 방식은 다르지만 비슷합니다. 

C언어에서는

double f(double x)
{
    return 6.0 * x + 9.0;
}

와 같이 데이터 type이 명확하게 표현되어야 하고, 연산자들은 생략할 수 없습니다.

정의된 함수를 호출할 때에는

double rsult;

rsult = f(3);

printf("%lf\n", rsult);

처럼 호출합니다.

 

그러나 C언어에서는 함수의 역할이 수학적인 계산으로만 사용하는 것이 아니라 각종 제어/처리/동작 등을 포함합니다.

예를들면,

void print(const char *name)
{
    printf("Hello %s\n", name);
}

는 입력받은 이름에 대해서 인사를 하는 기능을 하는 함수입니다.

int main(int argc, char **argv)
{
    print("홍길동");
    
    return 0;
}

실행결과)
Hello 홍길동

위와 같이 사용/결과가 화면으로 출력하는 기능을 하게 됩니다. 이와 같이 C언어의 함수는 function(계산) + procedure(처리)의 기능이 합쳐진 의미 있는 실행 단위입니다. 

 


function(함수)의 구조

return_type 함수명(파리미터_타입1 변수명1, ...)
{
    [local 변수 선언]
    
    [업무 로직 구현]

    return return값;
}

함수는 위와 같은 기본 구조를 갖습니다.

함수는 { ~ } 사이에 함수의 내용을 기술합니다. "{"는 block의 시작을, "}"는 block의 끝을 의미합니다. block은 범위를 한정한다는 의미도 있습니다. 즉, block 내에 선언된 변수는 block 밖에서 사용할 수 없는 등의 역할을 하고 위의 경우 함수의 범위는 { ~ } 사이로 한정한다는 의미가 됩니다.

위에 있는 return 예약어는 함수를 끝내는 것으로 return뒤의 return값의 데이터 type과 함수의 return_type의 데이터 type이 일치해야만 합니다. return은 함수를 실행하다가 특정한 조건에 함수를 끝내고 그 함수를 호출한 함수에게 결과를 전달하는 역할을 합니다.

 

이 들 함수를 몇 가지 case로 확인하도록 하겠습니다.

 


 

1). return이 없는 함수

/*
* 파라미터로 넘어온 수 만큼의 # 문자를 출력하는 함수입니다.
*/
void my_func(int count)
{
    int idx; 
    
    if(count <= 0) {
        printf("입력값이 올바르지 않습니다.\n");
        return;
    }
    
    for(idx = 0; idx < count; idx++) {
        printf("#");
    }
    printf("\n");
}

return이 없는 함수는 return type을 void로 표시합니다. 그리고 중간에 함수를 종료하기 위해서 return을 사용할 수 있는 데, 이 경우에 return 타입이 없기 때문에 return; 형태로 기술합니다. 또한 함수의 끝에서는 함수를 호출한 함수에게 전달할 데이터가 없기 때문에 return;을 붙일 필요가 없습니다.

 


 

2. 파라미터가 없는 함수

/*
* 이름을 입력받아서 인사하는 함수입니다.
*/
int hello(void)
{
    char name[50];
   
    printf("Enter your name: ");
    fgets(name, sizeof(name), stdin);

    printf("Hello %s\n", name);

    return 0;
}

파라미터가 없는 함수는 함수명 뒤의 괄호 안에 void를 입력합니다. 주로 input 데이터가 필요없거나 input 데이터를 내부에서 얻을 수 있는 경우에 사용할 수 있습니다. 함수의 return의 기능은 수학적 계산의 결과를 얻기도 하지만, 내부에서 처리가 잘되었는 지 여부를 판단하는 기준으로도 많이 사용합니다.  판단 기준이 되는 값은 무엇으로 할 지는 함수를 만드는 개발자 마음입니다만, 일반적으로 -1 또는 -값을 오류로 정의하곤 합니다. 정상은 0 또는 양수를 사용하곤 합니다. 그리고 함수앞에 있는 return type이 int이므로 정수형 데이터를 return 합니다.

 

※ hello(void)와 hello( )의 차이

함수를 사용하기 위해서는 함수의 prototype을 위쪽에 선언해야 합니다. 만약, hello라는 함수가 있는 데, 이를 선언하기 위해서

int hello(void);
또는 
int hello();

라고 했을 때에 이래나 저래나 같은 의미일까요? 서로 다른 의미가 있습니다.

int hello(void)는 hello라는 함수의 파라미터는 확실히 없다라는 의미이고, int hello( )는 hello라는 함수의 파라미터가 뭔지 모르겠다.라는 의미입니다. 원래 hello함수가 int hello(const char *name);이었다고 하면 int hello(void);로 선언하면 오류가 발생하지만 int hello();라고 하면 정상적으로 처리됩니다.

 

 


 

3. 파라미터와 return이 모두 있는 함수

/*
* 파라미터로 넘어온 데이터를 더해서 합을 return하는 함수
*/
int plus(int val1, int val2)
{
    return val1 + val2;
}

함수의 파라미터는 여러개 올 수 있으며, 파라미터는 type과 이름의 쌍으로 콤마(,)를 구분자로 여러 개 사용할 수 있습니다. 함수를 호출할 때에는  파라미터 type, 순서, 개 수를 잘 보고 호출할 때에도 값의 type과 순서, 개 수도 맞춰야 합니다.

 


main( )함수

Sample). hello.c

/* 
* 입력이 없으면 Hello World를, 입력이 있으면 입력된 이름에게 인사하는 프로그램입니다.
*/

#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    if(argc == 1) {
        printf("Hello World!\n"); 
    } else {
        printf("Hello %s!\n", argv[1]);
    }
    
    return 0; 
}

C언어는 main( )함수의 호출로 프로그램이 시작이 되고, main( )함수가 끝나면 프로그램이 끝납니다. main( )함수를 정의해야만 컴파일해서 실행파일을 만들 수 있습니다. 다른 함수는 프로그램 내에서 다른 함수에 의해서 호출되지만 C언어의 main함수는 실행의 시작이므로 OS(Operating System)에 의해서 호출됩니다. 따라서 main( )함수는 다른 함수와 다른 의미가 있습니다. 

 

main함수의 return 값은 OS가 정상 여부를 판단하는 용도로 사용하는 데, 대체로 0을 return하면 정상, 그렇지 않으면 프로그램에서 오류가 발생하여 종료된 것으로 인식합니다. 위의 프로그램을 컴파일 하고 그냥 실행하면

$ gcc -o hello hello.c

$ ./hello
Hello World!

와 같이 출력합니다.

만약 argument로 이름을 입력하면

$ ./hello 홍길동
Hello 홍길동!

처럼 출력합니다.

 

위와 같이 main함수의 파라미터는 OS에서 프로그램의 명령어를 실행할 때에 넘긴 argument 순서로 문자열로 넘어갑니다. 다만 첫 번째 파라미터는 명령어 자체가 됩니다.

 

 

sample). argument.c - main( )함수의 argument 출력

/* 
* OS가 이 프로그램을 실행할 때에 넘겨온 argument를 출력하는 프로그램입니다.
*/

#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    int idx;
    
    for(idx = 0; idx < argc; idx++) {
        printf("argv[%d] : %s\n", idx, argv[idx]);
    }
    
    return 0; 
}

위의 소스를 컴파일하고 실행을 한다면, ...

$ gcc -o argument argument.c

$ ./argument Hello world test
결과)
argv[0] : ./argument
argv[1] : Hello
argv[2] : world
argv[3] : test

처럼 명령어를 실행할 때에 넘어온 Argument를 순서대로 출력합니다.

    


함수의 규모

C언어는 개발자에 따라서 main( )함수 하나만으로도 개발할 수 있고, 여러 개의 함수로 나누어서 구현할 수도 있습니다. 그러면 함수의 규모(라인수)는 어느 정도가 적합할까요? 그것은 정해진 답은 없습니다만, main( )함수나 또는 기능의 중심이 되는 함수는 업무의 큰 흐름으로 알 수 있는 수십 줄 이내로 표현을 하는 것이 좋습니다. 그 이외의 함수들도 코딩 최대 라인수를 어느 정도 제약을 하는 것이 좋습니다. 라인 수가 너무 많으면 전체 흐름을 파악하는 데, 어려움이 있기 때문에 큰 기능 단위로 나누고 그 큰 기능이 너무 크면 또 하위 함수로 쪼개는 식으로 표현을 하도록 합니다. 모니터의 해상도에 따라서 다르겠지만 페이지 다운으로 4~5 페이지 이내에서 다 볼 수 있는 것이 바람직해 보입니다.

 

 

 

C Programming Language 문법

1. C 프로그래밍 언어는? 2. C언어 개발 환경 (실습 환경) 3. C언어의 컴파일 과정 4. C 소스 파일 구성 5. 주석문(Comment) 6. 식별자 명명 규칙 7. C 프로그래밍의 시작 - 함수 8. 변수와 상수 (정수형) 9. 변..

www.it-note.kr

 

'C언어 > 문법' 카테고리의 다른 글

9. 변수와 상수 (실수형)  (0) 2019.10.24
8. 변수와 상수 (정수형)  (0) 2019.10.23
7. C 프로그래밍의 시작 - 함수  (2) 2019.10.22
6. 식별자 명명 규칙  (2) 2019.10.22
5. 주석문(Comment)  (0) 2019.10.22
4. C 소스 파일 구성  (0) 2019.10.20
블로그 이미지

사용자 자연&사람

행복한 개발자 programmer since 1995.

Tag ,

댓글을 달아 주세요