최상단

컨텐츠

Function Pointer에 대한 짧은 생각.

글 정보

Category
컴퓨터 이야기
2008. 8. 18. 17:31

본문

본 문서는 포인터에 대하여 기본적인 사항을 이해하시고 함수포인터에 대한 이해도를 높이고자 하시는 분들을 위해 작성된 글입니다. 고수분들은 제발 부탁이니 skip 해주시구요..;; 제 마음대로 이해한 내용이다 보니 틀린 부분이 있을 가능성이 농후합니다. 지적 부탁드립니다.-ㅋ


C언어를 배우면서 가장 생소하면서도 어려운 부분은 포인터이라고 생각됩니다.. 하지만 어느정도 포인터에 대해 이해했다고 생각하는 순간- 눈앞에 펼쳐지는건-…함수포인터;

또 한번 좌절을 경험하게 되죠ㅠ

함수 포인터에 대해 설명하기 전에..

생뚱 맞지만 배열에 대해서 잠깐 언급하고자 합니다.


char name[10];

라는 변수를 선언했다고 했을 때.


name 이라는 변수는..name 배열의 이름이 되겠죠?… array가 시작되는 부분의 주소를 저장하는 변수가 됩니다.

다만, 메모리의 주소를 저장하고 있지만.. 우리가 일반적으로 사용하는 포인터와는 약간 다르죠?..

name이라는 곳에는 다른 주소값을 저장할 수가 없습니다.. 상수와 비슷하게 사용되죠-…


char *pname;

이라는 포인터를 선언했을 경우에는.. pname에는 다양한 메모리값들을 저장할 수 있죠?…


예제를 하나 볼까요?


int main()
{
    ///////////////////////////// ARRAY
    int arr[3] = {1,2,3};
    int arr2[3] = {4,5,6};

    int *par;
    par = arr;

    printf("par %d %d %d\n",par[0],par[1],par[2]);
    par = arr2;
    printf("par %d %d %d\n",par[0],par[1],par[2]);

    return 0;

}

result

[dev@bamboo:~/USER/hclee/tmp/test/fp ] ./a.out
par 1 2 3
par 4 5 6


par라는 포인터 변수에 배열의 이름을 각각 넣어서…똑같이 접근할 수 있음을 볼 수 있는 예제입니다.


자~~ 이 차이점을 기억하시면… 함수포인터를 이해하기도 쉬울것 같습니다..(저는 그랬습니다;;)


우리는 일반적으로 함수를 선언하여 사용하는것에는 익숙합니다.

int add(int a, int b)
{
    return a+b;
}

이렇게 정의해서 사용하죠?

또 하나 만들어보겠습니다.

int add2(int a, int b)
{
    char tmp[20];
    memset(tmp,0,20);
    sprintf(tmp,"%d%d",a,b);

    return atoi(tmp);
}


자~~..둘다 더하기 기능을 하는 함수입니다..add2함수는 a,b를 넣었을 때 ab형태로 출력되는 함수..이것도 더하기 맞죠?;;

여기에서..함수의 이름은…위에서 설명했던 배열의 이름과 같은 역할을 하게 됩니다..잘 기억하세요!ㅋ


typedef int (*functiontype)(int a, int b);
int main()
{
    //////////////////////////////// FUNCTION POINTER
    int x=5;
    int y=10;

    printf("add %d + %d = %d\n",x,y,add(x,y));
    printf("add2 %d + %d = %d\n",x,y,add2(x,y));

    int (*plus)(int a, int b);

    plus = add2;
    printf("plus %d + %d = %d\n",x,y,(*plus)(x,y));

    plus = add;
    printf("plus %d + %d = %d\n",x,y,plus(x,y));

    functiontype func_add;

    func_add = add;
    printf("func_add %d + %d = %d\n",x,y,(*func_add)(x,y));
    func_add = add2;
    printf("func_add %d + %d = %d\n",x,y,(*func_add)(x,y));

    return 0;
}

우선 윗 부분만 보세요.

int (*plus)(int a,int b);

라고 선언한 부분이 있죠?…

이 부분이 plus라는 변수를 return type이 int형이고, 인자로 int, int를 가지는 함수 모양의 포인터 변수를 선언하겠다는 말입니다.

포인터를 선언하는 모양이 독특할 뿐이지…그냥 포인터라고 생각하시면 되요-..

보통 int형 변수를 선언할 때 int *var로 선언하면…var라는 변수에 저장되어 있는 메모리에서  int size만큼 값을 읽어오겠다..라고 표현하는 것 처럼… 이 plus 변수 또한 똑같은 것입니다..

설명이 이상한가요?ㅜㅜ…(이해하셨다고 믿고..;)

그럼..위에 배열에서… 사용하듯이..포인터 변수에 메모리의 이름을 대입하죠?

자~~ 함수에서도 똑같이 사용합니다.

plus = add;

plus라는 포인터 변수는..add라는 함수가 시작하는 메모리 주소를 저장하게 되는데..

plus라는 포인터를 참조할 때.. 사용하는 형식은 return type이 int형이고 인자로 int, int를 가지게 된다는 것입니다.

자..그럼 호출을 한번 해볼까요?..

원래라면..포인터에 저장되어 있는 주소의 값을 가져오기 위해서는..*가 붙어야되죠?.

(*plus)라고 하면..어떻게 될까요? plus에는 add의 시작 주소가 저장되어 있으니.. 거기에 *를 붙이게 되면.

add 함수랑 똑같은 말이 되겠죠?;..(아..점점 설명이 이상해집니다ㅜㅜ..그렇지만 이해하셨다고 생각하고 pass)

그럼..add와 (*plus)랑 같은 거니까….add(x,y) 대신에..(*plus)(x,y)도 같은것이라고 볼 수 있겠습니다….

이해가 되나요?…ㅠㅠ


나머지..functiontype 으로 typedef 하여 사용하는 것도 똑같은 원리로 작동하게 되구요..

함수포인터를 조금이라도 편리하고..직관적으로 사용하기 위해서 사용하는 테크닉(?) 정도로 보시면 될 것 같습니다.


제가 전하고자 했던 내용은…함수의 이름과 함수를 저장할 수 있는 포인터..를 기존에 쉽게(?) 이해하고 있는 배열을 사용하여 설명드리고자 했던건데….전달이 잘 되었나 모르겠습니다.


저 처럼 헤메는 분들이 계실까봐..조금이라도 이해한 부분을 공유하고자 하는 것이니.

너그러운 마음으로 읽어주세요-ㅋ

트랙백과 댓글 여닫기

TOP