69.5 typedef로 함수 포인터 별칭 정의하기
지금까지 함수 포인터를 만들 때 int (*fp)(int, int);처럼 일일이 반환값 자료형과 매개변수 자료형을 명시해주었습니다. 이런 방식을 full pointer type이라고 하는데 사용하기가 상당히 번거롭습니다. 이때는 typedef로 별칭을 정의하면 함수 포인터를 매번 만들지 않아도 됩니다.
- typedef 반환값자료형 (*함수포인터별칭)(매개변수자료형1, 매개변수자료형2);
그럼 int형 반환값, int형 매개변수가 두 개인 함수를 뜻하는 함수 포인터 별칭은 어떻게 만들까요?
int add(int a, int b) // int형 반환값, int형 매개변수 두 개 { return a + b; }
이때는 typedef 뒤에서 함수 포인터를 만들면 됩니다.
typedef int (*FP)(int, int);
이제 함수 포인터 별칭을 사용해보겠습니다. 다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요.
typedef_function_pointer.c
#include <stdio.h> int add(int a, int b) // int형 반환값, int형 매개변수 두 개 { return a + b; } typedef int (*FP)(int, int); // FP를 함수 포인터 별칭으로 정의 FP getAdd() // 함수 포인터 별칭을 반환값으로 지정 { return add; // add 함수의 메모리 주소를 반환 } int main() { printf("%d\n", getAdd()(10, 20)); // 30: getAdd을 호출한 뒤 반환값으로 add 함수 호출 return 0; }
실행 결과
30
typedef가 앞에 붙는다는 점 말고는 일반적인 함수 포인터를 만드는 방법과 같습니다.
// ↓ 반환값 자료형 typedef int (*FP)(int, int); // fp를 함수 포인터 별칭으로 정의 // ↑ ↖ 매개변수 자료형 // 함수 포인터 별칭
다음과 같이 함수 포인터 별칭을 함수의 반환값 자료형으로 지정할 수 있습니다. getAdd의 모양이 훨씬 간단해졌죠?
FP getAdd() // 함수 포인터 별칭을 반환값으로 지정 { return add; // add 함수의 메모리 주소를 반환 }
물론 함수 포인터 별칭으로 포인터 변수(배열)를 선언하거나, 구조체 멤버 자료형, 함수의 매개변수 자료형으로도 사용할 수 있습니다.
use_of_typedef_function_pointer.c
#include <stdio.h> int add(int a, int b) // int형 반환값, int형 매개변수 두 개 { return a + b; } typedef int (*FP)(int, int); // FP를 함수 포인터 별칭으로 정의 struct Calc { FP fp; // 함수 포인터 별칭을 구조체 멤버 자료형으로 사용 }; void executer(FP fp) // 함수 포인터 별칭을 매개변수 자료형으로 사용 { printf("%d\n", fp(70, 80)); } int main() { FP fp1; // 함수 포인터 별칭으로 변수 선언 fp1 = add; printf("%d\n", fp1(10, 20)); // 30 FP fp[10]; // 함수 포인터 별칭으로 배열 선언 fp[0] = add; printf("%d\n", fp[0](30, 40)); // 70 struct Calc c; c.fp = add; printf("%d\n", c.fp(50, 60)); // 110 executer(add); // 150: executer를 호출할 때 add 함수의 메모리 주소를 전달 return 0; }
실행 결과
30 70 110 150
지금까지 함수 포인터의 다양한 활용 방법을 배웠는데 특히 문법이 복잡했습니다. 일단은 C 언어에서 함수 포인터가 이런 것도 가능하다 정도만 알아두면 됩니다. 나중에 필요할 때 문법을 찾아보면서 사용하면 됩니다.