함수 포인터

c or linux 2005. 2. 16. 05:47

오늘은 함수 포인터에 대해서 배워 보겠습니다.

함수 포인터는 말 그대로 함수를 가리키는 포인터 변수입니다. 여태껏 배워왔던 포인터와 똑같습니다.

여태껏 변수만을 가리키는 방법을 배워왔습니다.

하지만 포인터 변수는 함수도 가리킬수 있는 강력한 권한이 있습니다. 

저번에도 얘기했듯이 포인터 변수는 모두 4Byte입니다.

여지껏 배워온 포인터의 또다른 기법을 배워야 할것입니다.

포인터 변수에 함수의 시작번지를 저장시키고 저장된 시작번지의 주소를 가리키게 한후 실제 함수를

호출 하게 하면 끝입니다..

선언 하는 방법도 함수와 비슷하게 선언해줘야 합니다.

그래야 함수를 가리키는 포인터라고 인식을 하는거죠..

예를들어 다음과 같이 Start라는 함수가 있다고 봅시다.

이것을 포인터 변수가 가리키도록 해볼까요?

void Start()
{
   printf("안녕하세요");
}

void (*p)(); //함수를 가리키는 포인터 변수 4Byte짜리를 선언한다.

p = Start; // Start함수의 선두번지의 주소를 p포인터 변수가 가리킬수 있도록 p에 저장한다.

(*p)(); // p에 *를 붙이고 뒤에 ();를 붙여서 p가 가리키는 함수를 호출한다.

자 여기서 (*p)빼고는 Start와 리턴형과 파라미터가 없는것이 비슷합니다.

Start함수를 가리키기 위해서는 가리키는 함수와 똑같이 파라미터와 리턴값을 맞춰줘야 합니다.

void Start()
void (*p)()

자 (*p)와 이름만 틀릴뿐 비슷하죠?

자 여기서 *p가 붙어 함수를 가리키는 포인터 변수가 선언이 된것입니다.

함수를 가리키는 포인터 변수만 선언이 된것이지요.

포인터 변수에 Start함수의 시작주소를 저장시켜 볼까요?

p = Start;

Start 이름 자체는 함수의 시작번지를 가지고 있는 상수입니다!!!!!

그러므로 Start의 시작번지를 p에 저장하는 것입니다.

p가 가리키는 함수를 호출 해볼까요?

앞에 *를 붙여주면 자신이 가리키는 주소를 찾아가죠. 그리고 뒤에 ();를 붙여 함수를 찾아가라고

인식을 시켜줘야 합니다.

(*p)();를 호출하면 결국 Start();로 호출하는거와 똑같은 결과가 나타납니다.

결국 p가 가리키는 함수의 시작번지를 찾아가 Start()를 호출하는거죠.

자 다른 예제를 봅시다. 리턴값과 파라미터에 값을 전달하는 것입니다.

int Sum(int a, int b)
{
 printf("합은 [%d] 입니다",a+b);
 return a+b;
}

void main()
{
 int (*p)(int a, int b); //함수를 가리킬 수 있도록 포인터 변수 선언( 함수와 비슷하게 )

 p = Sum; //Sum함수의 선두번지를 p포인터에 저장

 int Value = (*p)(10,10); // p포인터가 가리키는 함수를 호출 리턴값을 Value에 저장

 printf("\r\n리턴값:%d", Value);
}

<결과>

합은 [20] 입니다
리턴값:20

다똑같죠 단지 (*p)이것만 해줬을 뿐이죠.

int Sum(int a, int b)를 가리키려면 반드시

int (*p)(int a, int b); <-- 이렇게 똑같은 형태로 변수를 선언해야 합니다.

(*p)이름을 변수처럼 자유롭게 사용할수 있죠..

포인터 변수라고 우선순위를 주기 위해서 괄호를 넣어 준것이구요.

아무튼 약간 이상해 보일지도 모르겠지만 이렇게 사용한다고 이해를 해두셔야 합니다.

마지막으로 알아야 할것은 함수를 가리키는 포인터 변수는 파라미터로 받을 수 있습니다.

당연히 변수니깐 파라미터로 받겠죠.

다음 예제를 봅시다.

void Hello()
{
  printf("Hello");
}

void Okay(void (*p)()) //파라미터를 함수를 가리키는 포인터로 파라미터를 받았습니다.
{
  (*p)(); //파라미터로 넘겨받은 선두번지를 찾아가 Hello함수를 실행합니다.
}

void main()
{
  Okay(Hello); // Hello함수의 선두번지를 파라미터로 넘겨준다.
}

이런식으로 아주 간단하게 넘길 수가 있습니다.

Okay파라미터에 void (*p)()를 그대로 넣어 줬습니다.

왜냐 함수를 가리키는 포인터는 변수이고 함수를 가리키기 위해서는 포인터 변수를 함수처럼

(*p)만 빼고 똑같이 선언해줘야 한다고 배웠습니다.

아무튼 리턴값과 파라미터는 항상 똑같이 해주어야 합니다 결코 잊지 마세요!

이상 함수 포인터를 마치겠습니다.

'c or linux' 카테고리의 다른 글

pthread 개념 - Application Development Guide --Core Components  (0) 2005.02.18
POSIX 쓰레드로 멀티 쓰레드 프로그래밍하기  (0) 2005.02.18
함수 포인터  (0) 2005.02.16
ctags 활용  (0) 2005.02.15
#ifdef __cplusplus  (1) 2005.02.12
Setjmp()  (0) 2005.02.11
Posted by 김용환 '김용환'

댓글을 달아 주세요