프로그래밍 언어/C언어

C언어 예시를 통해서 함수포인터 알아보기

원원 2022. 3. 4. 22:45

안녕하세요. 오늘은 C언어 함수포인터를 알아보겠습니다

함수포인터란 포인터를 만들어서 함수에게 사용하는것 입니다

 

예시1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
 
 
char func(int i, int j , char c) 
{
    return i+j+c;
}
 
int main()
{
    char (*p)(int,int,char); // 반환형 (*변수명)[전달인자];
    p = func;
    printf("%d \n",func(1,2,3));
    printf("%d \n",p(1,2,3));
}
 
cs

결과값

6

6

11번줄에서 함수포인터를 만듭니다. 주석에 나와있는 포맷을 사용하면 됩니다

12번줄에 func함수를 함수포인터p가 가리킵니다

14번줄에서 함수포인터로 함수를 불러옵니다

 

예시2) 함수가 여러 개 있는데 함수를 일일이 작성하지 않고 불러오는 방법이 있습니다. 함수포인터를 사용하면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
 
void func1(char c)
{
    printf("값:%d \n",c);
}
void func2(char c)
{
    printf("값:%d \n",c);
}
void func3(char c)
{
    printf("값:%d \n",c);
}
void func4(char c)
{
    printf("값:%d \n",c);
}
 
int main()
{
    void (*p_func[4])(char= {func1,func2,func3,func4}; // 반환형 (*변수명[배열개수])(전달인자);
    int i;
    
    for(i=0;i<2;i++)
        p_func[i](i);
    printf("-----------------------------------\n");
    for(i=0;i<4;i++)
        p_func[i](i);
}
cs

결과값

값:0
값:1
-----------------------------------
값:0
값:1
값:2
값:3

22번째줄에서 함수포인터를 배열로 만듭니다. 

26번째줄에서 p_func[0][0], p_func[1][1]을 호출합니다

27번째줄에서 p_func[0][0], p_func[1][1], p_func[2][2], p_func[3][3] 을 호출합니다

 

또 다른 예제

#include <stdio.h>
#define FUNC1
//#define FUNC2
//#define FUNC3

typedef ptrFunc(int a, int b);

#if defined FUNC1
int func(int a, int b)
{
   return a+b;
}
#elif defined FUNC2
int func(int a, int b)
{
   return a-b;
}
#elif defined FUNC3
int func(int a, int b)
{
   return a*b;
}
#endif

int calc(ptrFunc* ptr, int num1, int num2)
{
   return ptr(num1,num2);
}

int main()
{
   printf("Func : %d \n", calc(func,34,32));
   
}

 

main함수에서 매개변수를 func함수로 사용하는데 func함수는 FUN1,FUN2,FUN3가 define된거에따라 내용이 다릅니다. 


예시3) 함수포인터와 구조체사용하기
함수포인터와 구조체를 사용할 수 있습니다. 
1. get_info 함수 호출
메인 함수에서 temp.get_info를 사용하고 있지만, get_info의 함수 원형은 직접적으로 정의되어 있지 않습니다. 대신 get_info는 calc_TypeDef 구조체 안에 선언된 함수 포인터입니다.

2. calc_TypeDef 구조체
calc_TypeDef 구조체는 get_info와 set_info라는 두 개의 함수 포인터 멤버를 가지고 있습니다. 이들 함수 포인터는 각각 int (*get_info)(int a, int b)와 int (*set_info)(int a, int b)로 정의되어 있습니다.

3. temp 변수 초기화
temp 변수를 선언할 때, get_info와 set_info 함수 포인터 멤버에 각각 com_get과 com_set 함수의 주소를 할당합니다. 이 과정에서 temp.get_info는 com_get 함수의 주소를 가리키게 되며, temp.set_info는 com_set 함수의 주소를 가리킵니다.

4. 함수 원형
temp.get_info는 사실 com_get 함수의 포인터이므로, com_get이 실제로 호출됩니다. 그래서 temp.get_info를 호출하면, 이는 내부적으로 com_get을 호출하는 것과 같습니다. 즉, temp.get_info는 com_get 함수의 포인터이기 때문에 com_get의 함수 원형을 따르는 것으로 볼 수 있습니다.

#include <stdio.h>

int com_get(int z, int x)
{
	printf ("com_get   %d %d \n",z,x);
	return z+x;
}
int com_set(int z, int x)
{
	printf ("com_set   %d %d \n",z,x);
	z = 10;
	x = 20;
	return x-z;
}


typedef struct
{
	int (*get_info)(int a, int b);
	int (*set_info)(int a, int b);
}calc_TypeDef;


calc_TypeDef temp = 
{
	com_get,
	com_set,
};



int main() {
	temp.get_info(100,200);
	temp.set_info(200,300);
}