해당 글은 개인 공부 정리를 위해 작성되었습니다.
함수 포인터
프로그램에서 정의된 함수는 프로그램이 실행될 때 모두 메인 메모리에 올라갑니다.
배열명이 배열의 시작 주소값를 가리키는 포인터 상수를 의미하듯,
함수명은 함수가 정의되어 있는 메모리의 시작 위치를 가리키는 포인터 상수(constant pointer) 입니다.
함수명은 포인터이므로 printf에서 출력해보면 메모리 주소(%p)가 출력된다
※ 선언 방법 : 반환값자료형 (*함수포인터이름) (매개변수 자료형)
#include <stdio.h>
int add(int a, int b){ return a + b; }
int sub(int a, int b){ return a - b; }
int mul(int a, int b){ return a * b; }
int div(int a, int b) {return a / b; }
int main()
{
int funcNum;
int num1 = 0, num2 = 0;
//반환값자료형 (*함수포인터이름) (매개변수 자료형)
int (*fp)(int , int);
scanf("%d", &funcNum);
switch(funcNum)
{
case 0:
fp = add;
break;
case 1:
fp = sub;
break;
case 2:
fp = mul;
break;
case 3:
fp = div;
break;
default:
break;
}
scanf("%d %d", &num1, &num2);
printf("result %d\n", fp(num1, num2));
return 0;
}
함수 포인터 배열
※선언 방법 : 반환값자료형 (*함수포인터이름[크기])(매개변수자료형1, 매개변수자료형2);
#include <stdio.h>
int add(int a, int b){ return a + b; }
int sub(int a, int b){ return a - b; }
int mul(int a, int b){ return a * b; }
int div(int a, int b) {return a / b; }
int Calculator(int num1, int num2, int (*func)(int, int)) { return func(num1, num2); }
int main()
{
int funcNum;
int num1 = 0, num2 = 0;
int (*fp[4])(int , int);
scanf("%d", &funcNum);
switch(funcNum)
{
case 0:
fp[0] = add;
break;
case 1:
fp[1] = sub;
break;
case 2:
fp[2] = mul;
break;
case 3:
fp[3] = div;
break;
default:
break;
}
scanf("%d %d", &num1, &num2);
printf("result %d\n", Calculator(num1, num2, fp[funcNum]));
return 0;
}
typedef 키워드
typedef : 새로운 타입을 만드는 키워드이다.
typedef 키워드를 이용하면 복잡한 함수 포인터형에 새로운 이름을 붙일 수 있습니다.
※선언 방법 : typedef 자료형 (*함수 포인터명)(매개변수)
※사용 방법 : 선언된 함수 포인터명 별칭명
=ex)
typedef int (*FuncPtr)(int, int); // 선언
FuncPtr testptr; // 사용
아래는 "typedef 함수 포인터 새로운 타입명"을 사용한 예제이다.
typedef Handle (*getHandleFunc)(void* instance);
getHandleFunc getHandle;
Handle getEventHandle(void* instance);
void main(void)
{
void *instance;
..
..
getHandle = getEventHandle; //assign
getHandle(instance); //실제로는 getEventHandle 실행
}
Handle getEventHandle(void* instance)
{
//실제구현...
}
사용 영역
1. 콜백함수 -> 내부적으로 함수를 만들어서 직접 호출하지 않더라도, 함수의 매개변수로 호출 가능
아래 콜백 함수의 예시이다.
//A가 배포한 라이브러리 함수
//실제 소스코드는 B는 볼수 없음
//다만 A가 콜백을 구현 할 수 있도록 만듬
int sum(int a, int b, void (*funcptr)(int*,int*)) {
if (funcptr != NULL) {
funcptr(&a, &b);
}
return a + b;
}
//B가 만든 사용자 정의 함수 콜백용으로 만든 함수
void userdefine(int* a, int* b) {
if (*a < 0) *a = *a * -1;
if (*b < 0) *b = *b * -1;
}
int main() {
int result = 0;
result = sum(2, -2, NULL);
printf("콜백 함수 없이 호출 한 결과 : %d \n", result);
result = sum(2, -2, userdefine);
printf("콜백 함수를 정의하여 호출 한 결과 : %d\n", result);
return 0;
}
2. 구조체에 함수를 넣을 수 있다. -> 객체 프로그래밍 방식 구현 가능
3. Device driver
typedef struct {
const char *name;
void (*read) (byte *buffer, int count);
void(*write) (byte *buffer, int count);
} device_type;
device_type device =
{
"It's me",
device_read,
device_write
}
device_type *device_target;
device_target = &device
(*device_target->read)(buffer, count)
4.특정 주소번지로 branch
void (*example) (void);
example = (void (*)())0x7777;
(*example)();
(*(void(*)())0x7777)();
5. 하나의 프로그램이 여러 개의 파일로 분리되어 있을 때 다른 파일에 있는 정적 함수를 호출
'프로그래밍 언어 > c(일반)' 카테고리의 다른 글
[펌]RFID/NFC[3] (3) | 2024.11.27 |
---|---|
포인터(5) - 다중 포인터(이중포인터 위주) (0) | 2024.07.12 |
포인터(3) - 포인터&배열 함수인자 전달 (0) | 2024.07.12 |
포인터(2) - 포인터 배열 / 배열 포인터 (0) | 2024.07.11 |
extern 구조체 또는 변수 사용법 및 예시 (0) | 2024.05.08 |