프로그램을 실행하면 데이터는 메모리 영역중 데이터섹션(전역메모리, 스택메모리, 힙메모리)에 올라가는 반면기계어코드는 코드섹션에 위치하게 된다. 따라서 함수에 관한 코드 또한 메모리상에 위치하고 있으며, 함수의 이름이 메모리의 주소값이 된다.
함수 포인터란 ?
함수를 가리키는 포인터이다.
함수의 번지값과 함수 타입(리턴, 인수)에 대한 정보를 가지고 있다.
함수 포인터 변수
함수의 번지값과 함수 타입(리턴, 인수)을 저장하는 변수, "함수 포인터를 저장하는 변수"이다.
[문법]
자료형 (*변수이름)(인수...);
int Factorial(int n);
// 위의 함수에 대한 함수 포인터 변수는
int (*pf)(int) = Factorial;
// 한문장을 두 문장으로 표현하면
int (*pf)(int);
pf = Factorial;
C언어 설계자는 함수 포인터 변수를 만들 때 복잡해 보이는 이런 형태로 만든 것일까?
int* pArray[10]; // 포인터 배열
int (*pPointer)[10]; // 배열 포인터
추측한다면, 배열 포인터에서 일반적인 포인터와 다른 구조를 택했다.
일반적이지 않는 특수한 포인터에 대한 다른 구조가 필요했던 것이고
배열 포인터와의 통일성도 고려해 볼 필요가 있다.
따라서 특수한 포인트 변수의 경우 배열 포인터와 비슷한 형태로
(*변수이름) 이라는 형태로 만들었을 것이다.
int Add(int n1, int n2);
int Subtract(int a, int b);
int Multiply(int a, int b);
float Divide(int a, int b);
int Factorial(int n);
int (*pPointerOfFunction)(int, int);
pPointerOfFunction = Add;
pPointerOfFunction = Subtract;
pPointerOfFunction = Multiply;
pPointerOfFunction = Divide; // ?
pPointerOfFunction = Factorial; // ?
그렇다면 ?
배열 포인터를 저장할 수 있는 배열을 만들 수 있을까?
또는 함수 포인터를 저장할 수 있는 배열을 만들 수 있을까?
int* pArray[10]; // 포인터 배열
int (*pPointer)[10]; // 배열 포인터
// 과연 가능할까? 가능하다면 어떠한 형식으로 써야 할까?
int (*pPointer[5])[10]; // ?
int (*pPointer)[10][5]; // ?
int (*pPointerOfFunction)(int, int); // 함수 포인터
// 과연 가능할까? 가능하다면 어떠한 형식으로 써야 할까?
int (*pPointerOfFunction)(int, int)[5]
int (*pPointerOfFunction[5])(int, int)
// 예제
#include <stdio.h>
int Func1(int n)
{
return n+1;
}
int Func2(int n)
{
return n+2;
}
int Func3(int n)
{
return n+3;
}
int Func4(int n)
{
return n+4;
}
void main()
{
int (*pfArray[4])(int)= {Func1, Func2, Func3, Func4};
int a[3][2]= {1,2,3,4,5,6};
int b[4][2]= {1,2,3,4,5,6,7,8};
int c[5][2]= {1,2,3,4,5,6,7,8,9,10};
int d[6][2]= {1,2,3,4,5,6,7,8,9,10,11,12};
int (*apArray[4])[2]= {a, b, c, d};
printf("%d\n", pfArray[0](1));
printf("%d\n", pfArray[1](1));
printf("%d\n", (*pfArray[2])(1));
printf("%d\n", (*pfArray[3])(1));
printf("========================\n");
printf("%d\n", (apArray[0])[2][1]);
printf("%d\n", (apArray[1])[3][1]);
printf("%d\n", (apArray[2])[4][1]);
printf("%d\n", (apArray[3])[5][1]);
int (**ppf)(int) = pfArray;
printf("%p %p %p %p\n",Func1, Func2, Func3, Func4);
printf("%p %p %p %p\n",ppf[0], ppf[1], *(ppf+2), *(ppf+3));
for (int i = 0; i < 4; ++i)
{
printf("%d\n", (**(ppf+i))(1)); // by (*pfArray[2])(1)
printf("%d\n", (*(ppf+i))(1)); // by pfArray[2](1)
printf("%d\n", ppf[i](1)); // by *(ppf+i) == ppf[i]
printf("========================\n");
}
}