Coding & Programming/C언어 기초(A-Z)

[C언어 기초코딩: 예제로 간단 정리] 6. 함수(Function)

mainCodes 2021. 3. 11. 20:29

JollyTree의 C언어 기초코딩: 예제로 간단 정리 - 6. 함수(Function)

 

안녕하세요 JollyTree(•̀ᴗ•́)و입니다.

이번에는 C언어 함수에 대해 정리하려고 합니다. C언어는 기본적으로 main()이라는 함수에서 시작합니다.
아주 간단한 프로그램의 경우 main() 내에 기능을 구현해도 괜찮지만, 기능이 많고 복잡한 프로그램은 
main()함수 내에 모든 기능을 구현하면 가독성이 떨어지고, 수정, 개선 등 관리가 어려워 모듈화를 해야합니다.

int main(void)
{
    문장;
    ...
    return 0;
}

모듈화는 복잡한 프로그램의 기능을 쪼개서 크거나 작은 크기로 독립적 덩어리로 쪼개 놓는 것을 말합니다. 자동차를 예로 들면 자동차는 바퀴, 핸들, 엔진, 와이퍼, 에어콘 등으로 모듈화가 되어 있어 각각의 모듈을 개별적으로 제작, 생산한 후 하나의 자동차로 조립하듯이 프로그램도 기능별로 모듈화하여 하나의 프로그램으로 완성할 수 있습니다. 

C언어에서는 모듈화가 필요할 때 기본적으로 적용할 수 있는 방법이 함수입니다. 용어를 살펴보면 다음과 같습니다.


함수(Function) : 프로그램 코드의 일부로 특정한 기능에 필요한 코드를 모아 놓은 독립적인 부분
함수 호출(Function Call) : 독립적 코드로 만들어 놓은 함수를 호출 하는 것

아래 예제는 add()라는 이름의 함수를 정의하여 호출하고, 재사용하는 것을 보여주는 예제입니다,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
// 두 수(파라미터)를 입력받아 더한 후 결과를 반환하는 함수
int add(int a, int b)
{
    int c;
 
    c = a + b; //a, b를 인수(Argument)로 전달 받아 더하기
 
    return c;
}
 
int main(void)
{
    int a, b;
    int result;
 
    a = 10;
    b = 20;
 
    result = add(a, b);         //add() 함수를 호출하여 add()함수가 반환한 결과를 result 변수에 저장(대입)
    printf("result = %d\n", result);  //result 변수에 저장된 값을 출력
 
    result = add(a + 5, b + 10);    //add() 함수 호출, 재사용
    printf("result = %d\n", result);
 
    printf("result = %d\n", add(2030)); //add() 함수 호출 재사용
 
    return 0;
}
cs

 

실행결과(Output):

그럼 add()함수를 자세히 살펴보도록 하겠습니다. 함수명 add 앞의 int는 리턴 타입이라하며 함수 몸체가 실행된 후 결과를 호출한 곳으로 반환할 자료형입니다. 리턴 타입은 float, double, char, char* 등 C언어가 제공하는 자료형을 사용할 수 있습니다.

 

 int a, int b는 파라미터(매개변수)라고 하며, 개발자가 함수의 입력값으로 전달하고자 정한 것입니다. 보통 개발자가 함수기능을 설계하면서 두 수를 입력 받아 더하기 하는 프로그램을 만들어야 겠다라는 생각과 함께 기능에 맞는 파라미터 개수와 자료형을 정하게 됩니다. 구현되는 함수에 따라 아래와 같이 파라미터 개수는 여러개가 가능합니다.

 

int add(int a, int b, int result) ;  //add()함수 원형(function prototype)


아래 함수는 리턴 타입이 void입니다. 이 경우 이 함수는 별도로 호출자에게 특정 값을 반환하지 않고, c = a + b를 수행한 후 결과를 직접 화면에 출력하고 있습니다. 이렇게 함수 이름 앞에 void 라고 지정하면 이 함수는 아무런 값을 반환하지 않는 함수가 됩니다.

void add(int a, int b)
{
    int c;

    c = a + b;
    printf("result = %d\n", c);   

    //return 문이 없음
}

앞에서 함수를 설명하면서 자동차의 부품을 비유해서 말씀드렸는데, 함수를 만들 때 부품을 만든다고 생각하면 이해하기 쉽습니다. 부품을 만드는데 어떤 부품이 필요한지를 생각하는 것이 함수 이름, 헤더, 리턴 타입 기능 등을 정의하고 코딩하는 것과 유사하기 때문입니다.

일반적으로 간단한 프로그램은 함수를 main()함수가 정의된 라인보다 위에 정의할 경우 별도의 작업없이 main()함수에서 바로 함수를 호출할 수 있습니다. 하지만, 복잡도가 높거나 상황에 따라 .h 확장자를 가지는 별도의 헤더파일로 함수들을 모아 놓고 모듈화하여 관리합니다. 만약, main() 함수 보다 밑에 함수를 정의하거나, 별도의 .h 헤더파일로 모듈화를 해서 함수를 정의했다면 함수 원형(function prototype)을 미리 컴파일러에게 알려 주어야 합니다.  

main 함수 밑에 함수를 정의한 경우

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//#include를 이용하여 mymath.h를 포함
#include "mymath.h"        
 
int main(void)
{
    int c = square_func(10); 
    return 0;
}
 
void square_func(int a);
{
    int c;
 
    c = a * a;
    return c;
}
 
 
cs

 

별도의 .h 헤더 파일로 함수를 정의한 경우

main() 함수가 있는 소스코드에서 아래와 같이 #include를 이용하여 mymath.h를 포함합니다.

<mymath.h 파일 내용>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//#include를 이용하여 mymath.h를 포함
#include "mymath.h"        
 
int main(void)
{
    int c = square_func(10); 
    return 0;
}
 
void square_func(int a);
{
    int c;
 
    c = a * a;
    return c;
}
 
 
cs

위와 같이 mymath.h라는 별도 헤더 파일을 생성하여 #include 전처리 키워드를 이용하여 내가 만든 프로그램에 포함을 시켜줘야 컴파일할 때 에러가 발생하지 않습니다.

 

그리고 위 예제에서는 void sequre_func(int a) 함수의 몸체를 main() 함수가 있는 소스코드 파일에 함께 저장 했지만 일반적으로 모듈화를 위해서는 아래와 같이 mymath.cpp 파일을 별도로 만들어 프로젝트를 관리합니다.

 

<mymath.h 파일 내용(수정)>

int square_func(int a);
int add(int a, int b);  //함수 추가

<mymath.cpp 파일 내용>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "mymath.h"
 
int square_func(int a)
{
    int c;
 
    c = a * a;
 
    return c;
}
 
 
int add(int a, int b)
{
    int c;
 
    c = a + b; 
 
    return c;
}
cs

<test.cpp(main) 파일 내용>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include "mymath.h"
 
int main(void)
{
    int c = square_func(10);
    int d = square_func(20);
    int sum = 0;
 
    printf(">> c = %d, d = %d\n", c, d);
    printf(">> sum = %d\n", c + d);
 
    return 0;
}
cs

 

실행결과(Output):

C언어에는 컴파일러가 지원하는 다양한 함수 즉, 라이브러리 함수가 존재합니다. 컴파일러가 제공하는 함수는 개발자가 새로 개발할 필요가 없기 때문에 도서관에서 책을 빌려서 보듯이 편리하게 가져다 사용하면 됩니다.

 

아래 링크는 C언어 라이브러리 목록이니 참고하세요. 정말 많은 종류의 함수가 있습니다.

(참고) C언어 라이브러리 함수 테이블(출처 IBM) :  Standard C Library Functions Table, By Name

 

C언어 라이브러리는 화면출력, 키보드 입력, 수학 관련 함수 등 다양한 함수를 지원하므로 어떤 함수들이 존재하는지 대략적으로라도 알아둔다면 정말 유용하게 사용할 수 있습니다.

 

이상 JollyTree였습니다 (•̀ᴗ•́)و

 

(부록)

함수 예제:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#define _CRT_SECURE_NO_WARNINGS 1
 
#include <stdio.h>
#include <string.h>
 
//정수를 입력받는 함수
int get_int(void)
{
    int a;
 
    scanf("%d"&a);
 
    return a;
}
 
//두 수 중 큰 수를 반환하는 함수
int get_max(int a, int b)
{
    if (a > b)
        return a;
    else
        return b;
}
 
//두 수를 더하는 함수
int add(int a, int b)
{
    return a + b;
}
 
//두 수를 곱하는 함수
int mul(int a, int b)
{
    return a * b;
}
 
//전체경로에서 파일명만 잘라내는 함수
char* get_filename(char* path)
{
    //char path[256] = "c:\\test\\tistory.com\\codes.txt";
    static char filename[256= "";
    char* ptr = NULL;
 
    ptr = strrchr(path, '\\');
 
    if (ptr == NULL)
        strcpy(filename, path);
    else
        strcpy(filename, ptr + 1);
 
    return filename;
}
 
 
int main(void)
{
    int x, y;
    int result;
    char path[256= "c:\\test\\tistory.com\\mainCodes.txt";
    char filename[100];
 
    x = get_int();
    y = get_int();
 
    result = get_max(x, y);
    printf(">> 두 수 중 큰 수 : %d\n", result);
 
    result = add(x, y);
    printf(">> add 함수 호출 결과(덧셈) : %d\n", result);
 
    result = mul(x, y);
    printf(">> mul 함수 호출 결과(곱셈) : %d\n", result);
 
    printf("\n>> 입력한 전체 경로: %s\n", path);
    strcpy(filename, get_filename(path));
    printf(">> 추출한 파일명 : %s\n", filename);
 
    return 0;
}
cs

실행결과(Output):