69.7 연습문제: 계산 함수를 얻은 뒤 호출하기

다음 소스 코드를 완성하여 30, -10이 각 줄에 출력되게 만드세요.

practice_function_pointer.c

#include <stdio.h>

int add(int a, int b)
{
    return a + b;
}

int sub(int a, int b)
{
    return a - b;
}

struct Calc {
    _________________________
};

int executer(_______________, int a, int b)
{
    return fp(a, b);
}

          getFunc                                    
{
    return c->fp[index];
}

int main()
{
    struct Calc c = { { add, sub } };

    printf("%d\n", executer(getFunc(&c, 0), 10, 20));
    printf("%d\n", executer(getFunc(&c, 1), 10, 20));

    return 0;
}

실행 결과

30
-10

정답

 int (*fp[2])(int, int);
 int (*fp)(int, int)
 int (*getFunc(struct Calc *c, int index))(int, int)

해설

구조체 Calc의 변수를 선언하면서 초기화할 때 함수 addsub의 메모리 주소를 저장하고 있습니다. 따라서 Calc는 일단 함수 포인터를 멤버로 가지고 있습니다.

먼저 executer(getFunc(&c, 0), 10, 20)에서 가장 안쪽에 있는 getFunc부터 살펴봅니다. getFunc 함수 안에서는 c->fp[index]와 같이 구조체 포인터 c의 멤버 fp를 인덱스로 접근하여 요소를 반환하고 있습니다. 따라서 구조체 Calc의 멤버 fp는 함수 포인터 배열이며, int (*fp[2])(int, int);와 같이 만들어줍니다.

이제 getFunc 함수의 헤더 부분을 만듭니다. 함수 안에서 구조체 포인터 c와 정수형 index를 사용하고 있고, int형 반환값, int형 매개변수 두 개인 함수 포인터를 반환하고 있습니다. 따라서 함수 헤더는 int (*getFunc(struct Calc *c, int index))(int, int)와 같이 만들어줍니다.

마지막으로 executer 함수 안을 보면 fp(a, b)와 같이 함수를 호출하고 있습니다. 따라서 int형 반환값, int형 매개변수 두 개인 함수 포인터를 받을 수 있도록 매개변수 부분을 int (*fp)(int, int)와 같이 지정해주면 됩니다.