본문으로 바로가기

[C언어] 함수포인터

category C 2014. 6. 4. 11:35

프로그램을 실행하면 데이터는 메모리 영역중 데이터섹션(전역메모리, 스택메모리, 힙메모리)에 올라가는 반면기계어코드는 코드섹션에 위치하게 된다. 따라서 함수에 관한 코드 또한 메모리상에 위치하고 있으며, 함수의 이름이 메모리의 주소값이 된다.

 

함수 포인터란 ?

함수를 가리키는 포인터이다.

함수의 번지값과 함수 타입(리턴, 인수)에 대한 정보를 가지고 있다.

 

함수 포인터 변수

함수의 번지값과 함수 타입(리턴, 인수)을 저장하는 변수, "함수 포인터를 저장하는 변수"이다.

[문법]

자료형 (*변수이름)(인수...);

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");
 }
}