함수 포인터
프로그램 함수도 변수와 마찬가지로 생성될 시 컴퓨터 메모리에 올라가기 때문에 주소값이 있을 것임.
함수가 compile 되어서 memory loading시에 주소값이 배정된다.
다만 함수의 주소값은 한번 정해지면 바뀌지 않는다.
함수를 출력하게 되면 함수의 주소값이 찍힘.
이러한 함수의 주소값을 저장할 수 있는 변수가 함수 포인터이다.
메모리 참조값을 나타내는 변수 포인터의 타입과 달리
함수 포인터의 타입은 함수의 리턴타입을 의미한다.
함수 포인터 작성방법 :
(함수의 리턴형)(*포인터 이름)(첫번째 인자 타입, 두번 째 인자타입,...)
*함수의 원형 형태와 비슷하다고 보면 됨.
int fct(int a)
{
a++
return a;
}
라는 함수가 있다면
함수포인터는
int (*fPtr1)(int);
이렇게 작성하면 된다.
*함수 포인터의 형식에 맞는다면 어떤 함수도 이 포인터를 사용할 수 있게 된다.
#include <stdio.h>
int max(int a, int b);
int main(void)
{
int a, b;
int (*pmax)(int, int);
pmax = max;
scanf("%d %d", &a, &b);
printf("max(a,b) : %d \n", max(a,b));
printf("pmax(a,b) : %d \n", pmax(a,b));
return 0;
}
함수를 쓸 때 max(a,b)와 pmax(a,b) 두가지 형태 모두 가능하다.
void형 포인터
void형 포인터는 자료형에 대한 정보가 제외된, 주소 정보를 담을 수 있는 형태의 변수이다.
그리고 포인터 연산, 메모리 참조와 관련된 일에 활용 할 수 없다.(메모리에 대한 정보가 없기 때문)
int main(void)
{
char c = ’a’;
int n = 10;
void *vp;
vp = &c;
vp = &n;
. ....
여기서 void *vp가 void형 포인터인데 vp는 어떤 자료형의 변수의 값도 다 가질수 있게 된다.
int main(void)
{
int n = 10;
void *vp = &n;
*vp = 20; //Error!
vp++; //Error!
. ....
메모리를 참조 할 수 있는 정보가 없어서 접근해서 변형하려고 하면 에러가 난다.
그리고 void형 변수는 없지만 void형 포인터가 존재할 수 있는 이유는
포인터의 타입은 메모리 참조 크기를 나타내기 때문이다.
void형 포인터의 경우 포인터이기 때문에 포인터의 크기인 4byte가 메모리로 잡힌다.
그런데 이러한 void형 변수를 사용할 수 있게 하는 방법이 있는데 그것은 바로 형변환을 해주는 것이다.
#include <stdio.h>
int main(void)
{
void *a;
double b = 123.3;
a=&b;
printf("%lf \n", *(double *)a);
return 0;
}
a라는 void포인터에 (double *)명령어로 형변환을 해줌으로써 참조형태가 정해져서 참조가 가능해 진다.
따라서 일단 void형 포인터를 만들어서 형식에 구애받지 않고 주소를 담은다음 필요할 때에 형변환해서 쓰는 방식을 많이 사용한다고 한다!!