프로그래밍/C언어 C++언어

C/C++ - 함수포인터 (펌자료)

가카리 2015. 1. 25. 16:20
반응형

오늘은 함수포인터에 대해서 포스팅을 하도록 하겠습니다.


포인터가 무엇인지는 다들 아실텐데요, 특정 변수에 대한 메모리 주소를 담을 수 있는 변수를 포인터 변수라고 합니다. 그렇다면 함수포인터란, 특정 함수에 대한 메모리 주소를 담을 수 있는 것 이라고 정의할 수 있겠습니다.


함수포인터를 쓰는 이유는 무엇일까요?

 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

반응형