티스토리 뷰
함수포인터 (Function pointer)
포인터가 무엇인지는 다들 아실텐데요, 특정 변수에 대한 메모리 주소를 담을 수 있는 변수를 포인터 변수라고 합니다. 그렇다면 함수포인터란, 특정 함수에 대한 메모리 주소를 담을 수 있는 것 이라고 정의할 수 있겠습니다.
함수포인터를 쓰는 이유는 무엇일까요?
1. 프로그램 코드가 간결해집니다.
2. 함수포인터를 배열에 담아서도 사용할 수 있으므로 중복되는 코드를 줄일 수 있습니다.
3. 상황에 따라 해당되는 함수를 호출할 수 있으므로 굉장히 유용합니다.
그 외에도 함수 포인터를 이용하여 콜백함수를 구현할 수 있게 되는 등 편리하고 유용한 코드를 작성할 수 있게 됩니다.
우선 함수포인터의 모양에 대해 알아보도록 하겠습니다.
int (*FuncPtr) (int, int)
함수포인터는 위와 같은 모양을 띕니다. 함수의 프로토타입 선언과 모양이 비슷하죠?
함수의 프로토타입과 다른점이 있다면 함수 이름앞에 포인터를 가르키는 *이 붙는 다는 것인데요. 이렇게 선언이 되게 되면 FuncPtr 이라는 함수의 주소를 담을수 있는 '변수'가 생기는 것입니다.
이 FuncPtr 함수포인터가 담을 수 있는 함수는 위와 같은 모양을 띄어야 합니다. 즉, 함수의 리턴형은 int 여야하고, int형 파라미터 2개를 받는 함수여야 하는 것입니다.
예를 들어,
1: int add (int first, int second)
2: double div (double first, double second)
위의 보이는 두 함수가 있다고 가정할 때, 함수포인터의 선언 모양과 똑같이 생긴 add 라는 함수의 주소만을 담을 수 있는 것입니다.
아래의 사용 예제를 한 번 더 보시겠습니다.
1
2
3
4
|
FuncPtr = add (o) FuncPtr = &add (o) FuncPtr = div (x) FuncPtr = add() (x) |
1, 2 : 2가지 방법 모두 괜찮은 사용 방법입니다. 어떤 것을 쓰셔도 무관합니다.
3 : div는 FuncPtr의 선언 모양과 프로토타입이 달라서 사용할 수 없습니다. 에러가 발생합니다.
4 : add() 처럼 함수를 호출할 때 처럼 쓰는 것은 결과값이 함수의 호출 이후 리턴 값이 되는 것입니다. 따라서 add() 는 int형을 가리키게 되는 것이므로 사용방법 자체가 잘 못 되었습니다. 에러가 발생합니다.
이렇듯 함수포인터는 담고 싶은 함수의 프로토타입을 따라 선언하여 사용하시면 됩니다. 하지만, 이 모양이 복잡하기 때문에 typedef를 이용하여 타입의 모양을 단순화 시키는 작업을 해 줄수도 있습니다.
typedef int (*FuncPtr)(int, int)
프로그램 상단에 위와 같이 선언한 후, 실제 사용을 하실 때에는 FuncPtr 이라는 Type으로 새로운 변수를 사용하실 수 있습니다.
1
2
|
FuncPtr testFP = NULL; testFP = 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
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
|
#include <stdio.h> // 함수포인터 타입 정의 typedef int (*calcFuncPtr)( int , int ); // 덧셈 함수 int plus ( int first, int second) { return first + second; } // 뺄셈 함수 int minus ( int first, int second) { return first - second; } // 곱셈 함수 int multiple ( int first, int second) { return first * second; } // 나눗셈 함수 int division ( int first, int second) { return first / second; } // 매개변수로 함수포인터를 갖는 calculator 함수 int calculator ( int first, int second, calcFuncPtr func) { return func (first, second); // 함수포인터의 사용 } int main( int argc, char ** argv) { calcFuncPtr calc = NULL; int a = 0, b = 0; char op = 0; int result = 0; scanf ( "%d %c %d" , &a, &op, &b); switch (op) // 함수포인터 calc에 op에 맞는 함수들의 주소를 담음 { case '+' : calc = plus; break ; case '-' : calc = minus; break ; case '*' : calc = multiple; break ; case '/' : calc = division; break ; } result = calculator (a, b, calc); printf ( "result : %d" , result); return 0; } |
실행결과는 다음과 같습니다.
간단한 소스코드라 어려운 점은 없을 겁니다. 혹시 코드에 이해 안가는 부분이 있다면 댓글 남겨주시면 바로 답변 드립니다.
'Computer > C' 카테고리의 다른 글
함수포인터 & 멤버함수 포인터 관련 (0) | 2015.09.02 |
---|---|
함수 포인터 및 클래스 멤버함수의 함수포인터화 (0) | 2015.09.02 |
[Win32] 다른 프로그램의 윈도우 제어하기 (0) | 2015.03.15 |
[C언어] 연산자와 상수 (0) | 2015.02.24 |
scanf 함수 사용시 scanf_s 사용권고하며 오류 발생하는 경우 (0) | 2015.02.12 |