C 언어 - 함수 포인터

컴퓨터/C

728x90
반응형

함수의 정의 또한 메모리에 저장된다.

C언어를 배우면서 포인터를 배웠습니다. 다양한 변수들을 포인터를 통해 변수들이 저장된 메모리 주소로 접근하여 활용하게 되었습니다. 그렇다면, C언어를 통해 함수를 정의하면 정의된 함수는 어디에 저장되어 있을까요?

맞습니다. 정의된 함수 역시 메모리에 저장되게 됩니다. 그렇다는 것은 함수 또한 포인터를 통해 접근하고 이용할 수 있다는 것입니다.

본 포스트에서는 이 개념인 함수 포인터에 대해 알아보도록 하겠습니다.

 

함수가 정말로 메모리에 저장되는가 ? 

간단하게 확인해 보도록 하기위에 예제 소스를 작성해 보도록 합시다.

void func() {
	printf("함수도 메모리 주소가 있습니다.");
}

int main() {
	printf("%p\n", &func);
	return 0;
}

func라는 함수의명의 주소를 출력해보니 다음과 같이 나옵니다. 

이 근거로 보아 함수 또한 메모리 어딘가에 저장된다는 것을 알 수 있습니다.

 

함수 포인터 사용해보기

그렇다면, 함수 또한 포인터를 이용하여 사용할 수 있습니다. 그리고 C언어에서는 함수 포인터라는 문법으로 그 기능을 제공합니다. 

 

함수 포인터를 선언하는 방법은 다음과 같습니다.

리턴타입 (*포인터명)(매개변수);

예제의 함수를 담을 함수 포인터 변수는 다음과 같습니다

void *funcp ();

사용 방법은 포인터와 동일합니다. 

새로 만든 함수 포인터에 동일한 형태의 함수의 주소를 넣는다면 다음과 같이 사용할 수 있게 됩니다.

void func() {
	printf("함수도 메모리 주소가 있습니다.");
}

int main() {

	void(*funcp)();
	funcp = &func;
	funcp(); // 함수포인터를 이용한 함수 호출
    func(); // 함수 호출
	return 0;
}

그림처럼 함수 포인터변수를 만들고 그 안에 함수 메모리 주소를 대입시켜 사용할 수 있습니다.

 

함수 포인터 주의사항

당연한 말이지만 함수포인터를 만들려면, 담고자 하는 함수와 동일한 형태를 취해야 합니다.

즉, 반환타입 매개변수 타입 및 개수 등을 매칭 시켜주어야만 정상적인 함수 포인터로서의 역할이 가능합니다.

그리고 함수포인터를 선언할 때 꼭 (*함수 포인터명)으로 명확하게 함수 포인터를 의미하도록 표현해 주어야만 합니다.

 

왜 함수포인터가 필요한가?

자, 함수포인터를 이해했고, 사용하는 방법을 익혔다고 한다면 왜 쓰는지 알아야 될 필요가 있습니다.

함수 포인터가 왜 필요할까요? 함수 포인터를 사용하면서 가장 큰 장점은 함수를 변수처럼 취급할 수 있게 됩니다.

 

변숱처럼 취급을 하면 무슨 일을 할 수 있는지 몇 가지 예시를 들어 보록 하겠습니다.

 

  • 함수의 매개변수로 사용이 가능하다. (콜백 함수)

이 부분에 대해서는 조금 복잡하므로 다음 포스트에서 다루도록 하겠습니다.

 

  • 구조체에 함수를 넣을 수 있다.

C언어를 사용하면 절차지향 프로그래밍이라는 말을 많이 합니다. 맞는 말이지만 함수 포인터를 이용하면 이 한계를 어느 정도 극복할 수 있습니다. 

구조체에는 변수만이 존재해야 되지만, 함수 포인터 또한 변수입니다. 그래서 함수를 넣어 구조체에서 사용 할 수 있습니다.

void say() {
	printf("안녕");
}

typedef struct student {
	void (*func)();
}STUDENT;

int main() {

	STUDENT st;
	st.func = say;

	st.func();
	return 0;
}

이처럼 함수포인터를 이용하면 조금 더 C언어로 좀 더 효율적인 프로그래밍이 가능해집니다.

다음 포스트에서는 구조체에 함수를 넣는 기능 말고, 콜백 함수에 대하여 조금 더 알아보도록 하겠습니다.

728x90
반응형

'컴퓨터 > C' 카테고리의 다른 글

C 언어 - 비트연산  (0) 2022.02.20
C 언어 - CallBack함수(콜백함수)  (1) 2022.01.28
Visual Studio - Debug 와 Release (프로그램 배포)  (0) 2022.01.05
C 언어 - scan 무한 반복 에러  (0) 2021.12.01
C 언어 - 예외처리  (0) 2021.11.30

Commnet

G91개발일지

Gon91(지구일)

91년생 공학엔지니어의 개발일지

TODAY :

YESTER DAY :

TOTAL :