오늘은 함수포인터에 대해서 포스팅을 하도록 하겠습니다.
포인터가 무엇인지는 다들 아실텐데요, 특정 변수에 대한 메모리 주소를 담을 수 있는 변수를 포인터 변수라고 합니다. 그렇다면 함수포인터란, 특정 함수에 대한 메모리 주소를 담을 수 있는 것 이라고 정의할 수 있겠습니다.
함수포인터를 쓰는 이유는 무엇일까요?
1. 프로그램 코드가 간결해집니다.
2. 함수포인터를 배열에 담아서도 사용할 수 있으므로 중복되는 코드를 줄일 수 있습니다.
3. 상황에 따라 해당되는 함수를 호출할 수 있으므로 굉장히 유용합니다.
그 외에도 함수 포인터를 이용하여 콜백함수를 구현할 수 있게 되는 등 편리하고 유용한 코드를 작성할 수 있게 됩니다.
우선 함수포인터의 모양에 대해 알아보도록 하겠습니다.
int (*FuncPtr) (int, int)
함수포인터는 위와 같은 모양을 띕니다. 함수의 프로토타입 선언과 모양이 비슷하죠?
함수의 프로토타입과 다른점이 있다면 함수 이름앞에 포인터를 가르키는 *이 붙는 다는 것인데요. 이렇게 선언이 되게 되면 FuncPtr 이라는 함수의 주소를 담을수 있는 '변수'가 생기는 것입니다.
이 FuncPtr 함수포인터가 담을 수 있는 함수는 위와 같은 모양을 띄어야 합니다. 즉, 함수의 리턴형은 int 여야하고, int형 파라미터 2개를 받는 함수여야 하는 것입니다.
예를 들어,
1:int add (int first, int second)
2: doublediv (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> // 함수포인터 타입 정의 typedefint(*calcFuncPtr)(int, int); // 덧셈 함수 intplus (intfirst, intsecond) { returnfirst + second; } // 뺄셈 함수 intminus (intfirst, intsecond) { returnfirst - second; } // 곱셈 함수 intmultiple (intfirst, intsecond) { returnfirst * second; } // 나눗셈 함수 intdivision (intfirst, intsecond) { returnfirst / second; } // 매개변수로 함수포인터를 갖는 calculator 함수 intcalculator (intfirst, intsecond, calcFuncPtr func) { returnfunc (first, second); // 함수포인터의 사용 } intmain(intargc, char** argv) { calcFuncPtr calc = NULL; inta = 0, b = 0; charop = 0; intresult = 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); return0; } |
실행결과는 다음과 같습니다.
간단한 소스코드라 어려운 점은 없을 겁니다. 혹시 코드에 이해 안가는 부분이 있다면 댓글 남겨주시면 바로 답변 드립니다
출처 : http://norus.tistory.com/8
'프로그래밍 > C언어 C++언어' 카테고리의 다른 글
C/C++ - 전위 중위 후위 순위를 도입한 이진트리 (0) | 2015.01.25 |
---|---|
C/C++ - C를 이용한 간단한 이진 트리 예제 (0) | 2015.01.25 |
C/C++ - STL 라이브러리 string 함수 사용법 (3) | 2014.01.28 |