함수 포인터도 주소를 담는 변수일 뿐이다.

 

int 타입을 반환하고 int 하나를 인자로 받는 함수

int foo(int a){

... 

}

의 주소를 담는 포인터는

반드시 

int (*fooPtr)(int) = foo;

형식으로 선언해야 한다.

괄호를 안치면 int * fooPtr (int)가 되버리기 때문에 그냥 int (*fooPtr) (int)로 약속되었다 생각하자.

 

이때 fooPtr(22)처럼 일반 함수 호출하듯이 함수를 간접참조할 수 있는데 일반 포인터에 사용하는 *연산자는 붙이지 않아도 되지만, 내가 사용한다면 (*fooPtr)(33) 처럼 포인터임을 명시해야겠다는 생각이 든다. 

int b = fooPtr(22);        //ok

b = (*fooPtr)(33);    //ok

 

매개변수로 들어갈 때도 

void bar(int foo(int))       //ok

void bar(int (*foo)(int))    //:: error : C2084 'void bar(int (__cdecl *)(int,int))' 함수에 이미 본문이 있습니다.

이 둘은 같은 의미를 가진다.

 

함수포인터의 반환형은 조금 기억하기 힘들다.

다음은 제일 위의 int foo(int a)를 반환하는 returningFoo() 함수의 선언이다.

int ( *returningFoo() )(int){

... //근데 여기서 뭘 할까?

return foo;

}

 

따라서 함수포인터는 typedef를 해두면 편하게 사용할 수 있다.

typedef int (*fooPTR)(int);

fooPTR fptr = foo;

 

함수포인터는 qsort나 bsearch등의 매개변수로 들어가서 정렬이나 탐색의 기준이 될 수 있고, 콜백용으로도 쓰인다.

C++에서는 함수객체, 람다 등으로 대신할 수 있다.