프로그래밍 C언어

함수 (Function)

게임첫걸음 2024. 8. 14. 14:00

함수는 특정 기능을 하는 코드들을 묶어 하나의 명령어로 표현한 것입니다. 함수에 대해 알기 전에 먼저 알아야하는 것은 코드는 위에서 아래로 읽는 순서가 정해져있습니다. 때문에 함수를 이용해 기능을 코드 순서 상관없이 불러오는 것입니다.

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <stdio.h>
 
 
// 함수선언(Function Declaration)
// 반환형 함수명(매개변수)
void PrintHelloWorld();
 
int Sum(int _lhs, int _rhs);
int Sub(intint);
int Mul(int _lhs, int _rhs);
// Function Call Overhead
// Inline Function
inline float Div(float _lhs, float _rhs) {
    return _lhs / _rhs;
}
 
void Set100(int* const _pVal);
void Swap(int* const _lhs, int* const _rhs);
 
 
int main(void)
{
    // 함수(Function)
    // 함수호출(Function Call)
    PrintHelloWorld();
 
    // _lhs, _rhs: 매개변수(Parameters)
    // 3, 5: 인자(Arguments)
    int sum = Sum(35);
    printf("sum: %d\n", sum);

printf("sub: %d\n", Sub(5, 2);
 
    printf("Mul: %d\n", Mul(26));
 
    float div = Div(5.0f, 2.0f);
    float div2 = 5.0f / 2.0f;
 
 
    printf("\n");
 
 
    int val = 5;
    Set100(&val);
    printf("val: %d (%p)\n", val, &val);
 
 
    printf("\n");
 
 
    int lhs = 3;
    int rhs = 7;
    Swap(&lhs, &rhs);
    // lhs(7) - rhs(3)
    printf("lhs(%d) - rhs(%d)\n", lhs, rhs);
 
    return 0;
}
 
 
// 함수정의(Function Definition)
void PrintHelloWorld()
{
    printf("Hello, World!\n");
}
 
int Sum(int _lhs, int _rhs) {
    //int lhs = 100;
    //_lhs = 100;
    //return _lhs - _rhs;
    //if (_lhs > _rhs)
    return _lhs + _rhs;
}
 
int Sub(int _lhs, int _rhs) {
    return _lhs - _rhs;
}
 
int Mul(int _lhs, int _rhs) {
    return _lhs * _rhs;
}
 
void Set100(int* const _pVal)
{
    int val = 10;
    //_pVal = &val;
 
    *_pVal = 100;
    printf("_val: %d (%p)\n"*_pVal, _pVal);
}
 
void Swap(int* const _lhs, int* const _rhs)
{
    //return;
    //printf("a");
}
cs

 

함수는 세 가지로 기능이 나뉩니다.

  • 함수선언(Function Declaration)
  • 함수정의(Function Definition)
  • 함수호출(Function Call)

<함수선언>(Function Declaration)

void PrintHelloWorld();
int Sum(int _lhs, int _rhs);
int Sub(intint);
int Mul(int _lhs, int _rhs);
  • 함수선언은 반환형 함수명(매개변수)
  • 함수선언은 #define과 비슷한 성질을 이용하는 것으로 이 문서에서 사용할 함수명을 설정하는 것입니다.
  • 함수명은 축약어보단 어떤 기능을 하는 함수인지 한 번에 알 수 있도록 정확히 표현하는 것이 좋습니다. (ex) PrintHelloWorld
  • 매개변수는 함수에서 사용할 변수명이라고 생각하면됩니다. (ex) _lhd, _rhs

<함수정의>(Function Definition)

함수정의는 선언된 함수의 실질적 기능을 나타내는 겁니다.

void PrintHelloWorld()
{
    printf("Hello, World!\n");
}
 
int Sum(int _lhs, int _rhs) 
{
    //_lhs = 100;
    //return _lhs - _rhs;
    return _lhs + _rhs;
}
 
int Sub(int _lhs, int _rhs)
{
    return _lhs - _rhs;
}
 
int Mul(int _lhs, int _rhs) 
{
    return _lhs * _rhs;
}
 
void Set100(int* const _pVal)
{
    *_pVal = 100;
    printf("val: %d (%p)\n"*_pVal, _pVal);
}
 
void Swap(int* const _lhs, int* const _rhs)
{
   int temp = *_lhs; //temp = 임시
*_lhs = *_rhs; //포인터_lhs에 포인터_rhs값
*_rhs = temp; //포인터_rhs에 temp값인 *_lhs값
return; //반환
}

 위의 코드에서 선언한 함수들의 기능들을 정리해보겠습니다.

  • HelloWorld 출력 함수
  • _lhs, _rhs를 매개변수로 사용하는 더하기 Sum함수
  • _lhs, _rhs를 매개변수로 사용하는 빼기 Sub함수
  • _lhs, _rhs를 매개변수로 사용하여 곱하기 Mul함수
  • 상수화된 *_pVal을 매개변수로 받는 Set100함수로 _pVal의 초기값과 주소를 출력하는 함수 
  • 상수화된 *_lhs와 *_rhs를 매개변수로 받는 Swap함수로 값을 서로 바꿀 때 사용하는 함수

함수 내에서 값을 바꿀 수 있는 건 포인터 뿐입니다. 여기서 Swap 함수 중 temp 변수를 왜 쓰지? 그냥 *_lhs = *_rhs / *_rhs= *_lhs하면 되는 거 아닌가? 할 수 있는데 코드는 위에서 아래로 읽듯 함수 내에서도 똑같이 진행됩니다. 만약 저 두 코드만 함수에 존재한다면 출력할 때 lhs와 rhs의 값은 둘 다 초기화된 lhs값이 됩니다. 이건 함수호출에서 다루겠습니다.

 

<함수호출>(Function Call)

int main(void)
{
    PrintHelloWorld();
 
    // _lhs, _rhs: 매개변수(Parameters)
    // 3, 5: 인자(Arguments)
    int sum = Sum(35);
    printf("sum: %d\n", sum);
printf("sub: %d\n", Sub(5, 2);
    printf("Mul: %d\n", Mul(26));
 
//인라인 함수: 함수선언비용이 적으면 컴퓨터가 자체적으로 최적화 시켜주는 함수
    float div = Div(5.0f, 2.0f);
    float div2 = 5.0f / 2.0f;
 
    printf("\n");
 

 

    int val = 5;
    Set100(&val);
    printf("val: %d (%p)\n", val, &val);
 
    printf("\n");
 
    int lhs = 3;
    int rhs = 7;
    Swap(&lhs, &rhs);
    // lhs(7) - rhs(3)
    printf("After swap: lhs=%d, rhs=%d\n", lhs, rhs);
    return 0;
}

 

 함수호출은 정의된 함수의 기능을 불러와 실질적으로 사용하는 역할을 수행합니다. main 내 { } 중괄호 안에 위치하고 순서대로 호출된 함수의 출력값을 정리하겠습니다.

Hello, World

sum: 8

sub: 3

mul: 12

val: 100 (*_pVal의 주소값)

val: 5 (val의 주소값)

After swap: lhs=7, rhs=3 입니다.

HelloWorld sum, sub, mul 는 스킵하겠습니다.

  • 인라인 함수는 함수 호출을 함수 내용으로 대체하여 함수 호출 비용을 줄이는 최적화 기법입니다. 작은 함수에서 효과적이고 컴파일러가 자동으로 처리하는 함수입니다. 한 마디로 호출하지않고 정의에서 바로 사용하는 방식입니다. 현재 위의 예제에는 없지만, 사용하고 싶다면 함수 정의할때 함수명에 inline 키워드를 붙이면 사용 가능합니다. void inline sum ( ) { } 이런 느낌입니다.
  • Set100에 대한 출력값은 함수정의에서 이미 따로 100의 값과 출력코드를 설정해놓았기 때문에 val: 100 (주소값)이 먼저 출력하고 다음 호출에서 다룬 val = 5를 대입하여 val: 5 (&val)이 출력됩니다.
  • Swap 함수에서 lhs와 rhs값의 교환을 정의해놓았고 그에 대한 인자를 주었으니 lhs는 rhs의 값, rhs는 lhs의 값으로 출력됩니다.
  • 여기서 인자란 매개 변수에서 다루는 값을 뜻합니다. lhs와 rhs가 매개변수, 3과 7이 인자입니다.

 

 

'프로그래밍 C언어' 카테고리의 다른 글

동적 메모리 할당 (Dynamic Memory Allocate)  (0) 2024.08.18
문자열 (String)  (0) 2024.08.16
포인터 (pointer)  (0) 2024.08.13
배열 (Array)  (0) 2024.08.12
반복문(Loop)  (1) 2024.08.11