본문 바로가기
프로그래밍/C || CPP

[C/C++] 함수포인터(function pointer) 정리

by _BlankSpace 2017. 5. 30.


 0.  서론 

오늘은 어떤 걸 정리해볼까 생각을 하다가 문득 함수포인터에 대해서 생각이 났습니다. 그래서 바로 정리를 하고자 부랴부랴 공부(공부라고 쓰고 베껴 적기라고 말한다)를 했습니다. 예전 C 언어 공부를 할 때는 포인터는 어렵지만 알아가는 재미에 점점 재미를 붙였는데 함수포인터는 그닥 재미를 느끼지 못했습니다. 그래서 왜 그럴까 생각을 해봤습니다... 결론은.. 함수포인터를 자주 사용하지 않아서라고 잠정 결론을 내게 되었습니다..


함수 포인터를 공부하면서 느낀 점은 코드 정리가 편할 것 같았습니다. 앞으로 함수포인터에 대해서 정리하겠지만, 비슷한 함수들의 기능을 하나로 묶어서 함수포인터로 정리해놓는다면, 나중에 사용할 때는 비슷한 정리를 쉽게 사용할 수 있을 것 같다는 생각이 들었습니다.


어쨌든, 이러한 생각은 사용자가 직접 보고 느끼는 게 가장 빠른 길이라고 생각합니다. 그럼 정리를 시작하겠습니다.


  1. 함수포인터란?

함수 포인터(function pointer)는 데이터 값을 가리키는 대신에 메모리 내에서 실행 가능한 코드를 가리킵니다. 역참조[각주:1]될 때, 함수 포인터는 가리키는 함수를 보통의 함수 호출처럼 작동시키고 인자를 보내는 데 사용할 수 있습니다.

이러한 동작은 함수가 고정된 이름이나 주소를 사용해서 직접적이 아닌 변수를 통해서 간접적으로 호출되므로 '간접'호출이라고도 합니다.


 2. 함수포인터의 사용 방법 

함수 포인터의 선언 방식은 다음과 같습니다.


함수의 type (*함수포인터명) 함수전달인자);


FuncPtrEx1.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
int Plus(int x, int y)
{
    return x + y;
}
int main(void)
{
    int a = 10, b = 15;
    int sum;
    int (*funcPtr) (intint);
    funcPtr = Plus;
    sum = funcPtr(a, b);
    printf"%d + %d = %d\n", a, b, sum);
    return 0;
}
cs


결과:

 >> 10 + 15 = 25

int (*funcPtr) (int, int);

위의 코드는 함수의 type (*함수포인터명) 함수전달인자); 로 이루어져 있습니다.

하나의 형태로 정의를 해놓았다고 생각하면 되겠습니다.


이러한 형태로 정리를 한다면 


int Plus(int x, int y)


위의 식과 같은 형태는 모두 대입하여 함수 포인터로 호출할 수 있습니다.

두 개의 식은 (*funcPtr), (Plus)만 차이가 있다는 것을 볼 수 있습니다. 이처럼 *funcPtr은 함수의 포인터 저장할 변수라고 생각하면 되겠습니다.


따라서 

sum = Plus(a, b); 식은 다음과 같습니다.

sum = funcPtr(a, b);

sum = (*funcPtr) (a, b);


하지만 예제 하나로는 감이 안오실 수 있을 것입니다. 따라서 다음 예제로 함수 포인터 정리를 마무리하겠습니다.



FuncPtrEx2.cpp

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
#include <stdio.h>
int Plus(int a, int b)
{
    return a + b;
}
 
int Minus(int a, int b)
{
    return a - b;
}
 
int Multiply(int a, int b)
{
    return a * b;
}
 
int main(void)
{
    int a, b, res;
    int (*funcPointerArray[3]) (intint= {Plus, Minus, Multiply};
 
    for (a = 0; a < sizeof(funcPointerArray) / sizeof(funcPointerArray[0]); a++ )
    {
     res = funcPointerArray[a](3510);
     printf(" res = %d\n", res);
    }
    return 0;
}
cs


결과:

 >> res = 45

 >> res = 25

 >> res = 350

함수포인터를 사용하면 20 열의 방법처럼 정의도 가능하게 됩니다.

  

int (*funcPointerArray[3]) (int, int) = {Plus, Minus, Multiply};

함수 포인터를 3개의 배열로 정의한 것입니다. 그 방에는 Plus, Minus, Multiply를 가리키는 함수포인터 배열이 되는 것입니다.


[0]            [1]             [2] 

 Plus

Minus 

Multiply 


이런 식으로 배열 식의 함수포인터를 정의함으로써, 각각의 함수를 가리키는 함수포인터 배열이 될 수 있습니다.

계속해서, 22열을 보면 sizeof(funcPointerArray) / sizeof(funcPointerArray[0])

하나의 배열 방에서 전체 배열방을 나눔으로써, 배열 방의 개수를 구할 수 있습니다. 이것을 이용하여, for문인 반복문으로 함수를 적용할 수 있다는 것을 볼 수 있습니다.


이처럼 함수포인터를 직접 적용하려면 초반에는 어려움이 있겠지만, 잘 사용한다면 코드의 가독성을 줄 수 있는 좋은 방법이 될 수 있으리라 생각합니다.

이상 함수포인터에 대해 정리를 마치겠습니다.


제 글이 도움이 되셨거나 공감이 되시는 부분이 있으셨다면, 밑에 있는 공감 버튼 한 번씩 꾸욱 눌러주시면 감사하겠습니다.


공감 버튼은 저에게 큰 도움이 됩니다. 감사합니다.





















-

-

-

-

  1. 포인터의 역참조 연산자 *은 주소를 받아서 주소에 저장된 값을 가져오는 연산자를 뜻합니다. 즉, 포인터 주소에 있는 데이터를 읽기 위해서 사용한다고 생각하면 되겠습니다. 반대로 포인터 주소에 데이터를 대입할 때도 사용됩니다. ex) int* addrOfData = &address; int data = addrOfData; [본문으로]

댓글