sonumb

C Pointer - 2 본문

개발자 이야기/C/C++

C Pointer - 2

sonumb 2008. 2. 13. 15:59

저번시간에 이어 두번째로 이번에는 함수 포인터를 설명하겠다.
일단 들어가기 전에 두가지 정도 알려줄려고 한다.
첫째 함수 포인터는 어따 써먹는가/
뭐 용도가 있었으니 커니건,리치옹께서 만들지 않았겠나? (퍽퍽~)
각성하고...
보통, `포인터`가 들어가면 `Dynamic`이란 말과 꽤나 연관이 있어진다.
compile-time이 아닌 run-time에 결정을 해야한다는 소리인데..
그러면 함수랑 연관 시켜 뜻풀이를 시도해보자..

함수,즉 어떻게 해야할 일이 run-time에 서로 달라져야 한다.

그러면 보통 운영체제랑 연관시켜 보자. Task Switching이 대표적이 예라 할 수 있겠다. ( 솔직히 커널이나 시스템 프로그래밍아니면 응용한 곳이 거의 없다. -_-;).
생각해보자.
커널이라는 프로그램은 우리가 만든 프로그램을 돌린다.
아무생각없이 있지만 말고, 생각해보라. 프로그램이란 것은 보통 전체적인 컴파일 후에 실행이 되는 것이 아닌가? 그럼 우리가 만든 프로그램을 실행하기 위해서는 커널 메모리 안에 적절히 배치를 해야 할 것이고 그렇게 하기 위해서는 우리가 만든 프로그램을 커널소스에 넣어 컴파일을 해야할 것이다.
하지만, 그렇게 하려면, 맨날컴파일을 해야 할 것이다. 하지만 포인터라는 개념이 있기에 우리는 쉽고도 효율적으로 프로그램을 사용하는 것이다.
 
두번째 함수명은 도대체 뭐냐? ( 이걸 평소에 생각해본 사람 있겠나? :p)
예를 들어

void function( int );
라는 프로토타입인 선언된 경우 .
아시다 시피 void는 return type이고 function은 함수명이고,
int는 parameter의 타입이다.
여기서 function은 함수의 시작주소의 Label이다.( 절대 variable 이 아니다.)
다음을 통해 알아보자.

#include <stdio.h>
void function( int a ){
     printf("function:%d\n",a);
     return;
}
int main( void )
{
  printf("function : %x \", function );
  return 0;
}

처음부터 어렵고 혼동이 오기 시작한다. :P

그건 그렇고 그럼 저건 대체 어떻게 저장하란 말이냐.
int main( void )
{
  void (*pfn)(int);    // 이제야 변수가 되었다.
  pfn = function;         // 아싸~ 대입하고~
  /*
   *   function = pfn;     // error!!! 대입이 안되므로 변수가 확실히 아니다.
   */
  (*pfn)(3);            // 호출도 해보고~
  return 0;
}
일단 첫번째 결론은 보통의 함수명은 변수가 아니라 Label, 즉 상수값일 뿐이다. 잘 기억하자.

void (*pfn)(int);
   
함수 포인터는 대입하고자 하는 함수와 Function Signature가 같아야 한다.
 (Function Signature : return type과 parameter type과 parameter의 개수.)
다를시에는 컴파일타임에 에러가 나던가 워닝이 뜨던가 할 것이다.(컴파일러마다 다르다.)

(*pfn)(3); 
호출은 일반 포인터 변수와 같이 asterisk를 붙여주면 되겠다...


자 이번엔 일종의 팁인데..
위에서 강조한 것을 바탕으로 퀴즈하나 풀어보자.
문제1. 포인터랑 배열이랑 같은거에염?
배열의 이름은 변수가 아니걸랑요. Label입니다. :p
따라서 포인터변수랑 배열이랑 같다라는 말은 개미 똥싸는 소리!
누가 배열이랑 포인터랑 같다라고 가르쳐주면 얼른 딴사람한테서 배워라. :p
반응형