프로그래밍 C언어

함수 포인터(Function Pointer)

게임첫걸음 2024. 9. 10. 14:47

 이번 글은 C언어의 함수 포인터(Function Pointer)에 대해 알아보겠습니다. 함수포인터는 기존의 주소값 저장하던 포인터기능을 함수에 접목하여 함수를 호출하는 대리자의 역할을 대신하는 겁니다. 이는 C#의 대리자(delegate)와 비슷한 기능을 합니다. 컬렉션 글에서 대리자를 다룬 적이 있으니 관심이 있으시면 살펴보시면 될 것 같습니다. ㅎㅎ

컬렉션(Collections) (tistory.com)

 

컬렉션(Collections)

컬렉션이란? 아래의 기능을 사용하여 여러 개의 데이터를 하나의 구조로 그룹화하여 관리하는 기능입니다. using System.Collections;using System.Collections.Generic; //컬렉션에서 제네릭을 사용하기 위한

hwangameinformation.tistory.com

 그래도 짧게 대리자에 대해 적어보겠습니다. 대리자는 메서드의 참조를 담고 있는 변수 겸 타입으로 메서드의 시그니처(반환형, 매개변수)를 지정하며 콜백 메서드로서의 역할을 합니다. 여기서 C언어의 함수 포인터와 유사한 기능이 많은데

  1. 반환형과 매개변수로 정해짐. (대리자에선 메서드의 반화형, 매개변수를 지정하는 것과 같습니다.
  2. 함수를 담고있습니다. (대리자에선 메서드를 담고있습니다.

대리자의 기능 그림 예시
함수포인터 그림 예시

그림으로 봤을 땐 비슷한 느낌이 들지 않지만, 풀어 해석하면 함수 포인터는 위의 대리자와 같은 과정을 거칩니다. 이제 코드를 살펴보겠습니다.

#include <stdio.h>

//반환형과 매개변수로 정해짐
void PrintHello()
{
	printf("Hello\n");
}

void PrintWorld()	
{
	printf("World\n");
}

int Sum(int _lhs, int _rhs)
{
	return _lhs + _rhs;
}

int Sub(int _lhs, int _rhs)
{
	return _lhs - _rhs;
}

void main()
{
	// 함수 포인터(Function Pointer)
	void (*pFunc)() = PrintHello;	//PrintHello()가 매개변수가 없기 때문에 포인터를 넣을 수 있음.
	pFunc();
	pFunc = PrintWorld;
	pFunc();
	//출력: Hello \n World

	int(*pCalc)(int, int) = Sum;	//Calc 함수 pointer에 Sum함수를 다룸. 
	printf("Sum: %d\n", pCalc(2, 5));
	pCalc = Sub;
	printf("Sub: %d\n", pCalc(2, 5));
}

함수 2개 정의합니다.

  • PrintHello: Hello 출력하는 함수
  • PrintWorld: World 출력하는 함수
  • Sum: int 자료형의 매개변수 _lhs와 _rhs를 합치는 함수
  • Sub: int 자료형의 매개변수 _lhs와 _rhs를 빼는 함수

이제 main 함수에서 함수포인터를 이용합니다.

  • void (*pFunc)() = PrintHello; : *pFunc 포인터함수에 PrintHello 함수의 주소를 할당합니다. 여기서 (*pFunc)로 괄호를 묶은 이유는 컴파일러에서 반환형인 void와 void*의 혼동을 방지하기 위해서입니다. (  ) 괄호로 안닫으면 오류걸립니다.
  • pFunc(); : pFunc 함수가 가리키는 함수를 호출합니다. printHello 함수 주소를 가리키고 있으므로, PrintHello가 호출되며 "Hello"가 출력됩니다.
  • pFunc = PrintWorld; : 함수는 함수명 자체가 첫 주소를 가르킵니다. 즉, pFunc에 PrintWorld 함수의 주소를 할당합니다. 이제 pFunc은 PrintWorld를 가리키게 됩니다.
  • pFunc(); : PrintWorld를 가리키고 있으니 PrintWorld가 호출되고 World가 출력됩니다.

여기서 pFunc() 함수 포인터는 C#의 대리자와 동일한 역할을 수행하는 중개업자와 같은 역할이라고 생각하면 됩니다. 그리고 마지막 네 줄을 해석하겠습니다.

  • int(*pCalc)(int, int) = Sum; : int 반환형에 int 2개를 매개변수로 가진 *pCalc 함수포인터에 Sum함수 주소를 할당합니다. 
  • printf("Sum: %d\n", pCalc(2, 5)); : 2와 5를 매개변수로한 Sum함수를 호출하여 Sum: 7이 호출됩니다.
  • pCalc = Sub; : pCalc에 Sub함수 주소를 할당합니다.
  • printf("Sub: %d\n", pCalc(2, 5)); : 2와 5를 매개변수로한 Sub함수를 호출하여 Sub: -3이 출력됩니다.

'프로그래밍 C언어' 카테고리의 다른 글

퀵 정렬(Quick Sort)  (0) 2024.08.27
버블 정렬(Bubble Sort)  (0) 2024.08.27
삽입 정렬 (Insertion Sort)  (0) 2024.08.27
선택 정렬(Selection Sort)  (0) 2024.08.27
이진 트리 (BinaryTree)  (0) 2024.08.25