함수 포인터란?
- 함수의 주소를 저장하는 변수
필요성
- 프로그램 코드 간결화
- 배열로 처리함으로써 중복 코드 제거 가능
- 상황에 따른 함수 호출
- 함수를 데이터 형태로 처리 → 함수의 보관과 전달이 용이
형식
- 리턴 타입 (*함수 포인터명)(매개변수 리스트);
1. 리턴과 매개변수가 없는 함수에 대한 함수 포인터
#include <stdio.h>
void hello()
{
printf("Hello, world!\n");
}
void good()
{
printf("Good morning!\n");
}
int main()
{
void (*fp)(); // 함수 포인터 선언(리턴타입void, 매개변수 없음)
fp = hello; // hello 함수 시작 주소를 대입
fp(); // 함수 포인터로 호출
fp = good; // good 함수 시작 주소를 대입
fp(); // 함수 포인터로 호출
return 0;
}
2. 리턴과 매개변수가 있는 함수에 대한 함수 포인터
#include <stdio.h>
int add (int a, int b) { return a + b; }
int sub (int a, int b) { return a - b; }
int main()
{
int (*fp)(int, int); // int를 리턴하고, int형 2개를 매개변수로 하는 함수 포인터 선언
fp = add; // 함수 포인터에 add함수 대입(함수 포인터의 타입과 매개변수가 동일해야 대입 가능)
printf("%d\n", fp(10, 20)); // 함수 포인터 호출
fp = sub; // 함수 포인터에 sub함수 대입
printf("%d\n", fp(10, 20)); // 함수 포인터 호출
return 0;
}
3. 함수 포인터 배열
배열 사용 전
#include <stdio.h>
int add (int a, int b) { return a + b; }
int sub (int a, int b) { return a - b; }
int main()
{
int funcNumber;
int num1, num2;
int (*fp)(int, int) = NULL; // 선언 단계에서 따로 초기화 하지 않으면 가능하면 NULL로 초기화
printf("함수 번호와 계산할 값을 입력하세요: ");
scanf("%d %d %d", &funcNumber, &num1, &num2);
switch(funcNumber)
{
case 1:
fp = add;
break;
case 2:
fp = sub;
break;
}
printf(%d\n", fp(num1, num2));
return 0;
}
배열 사용 후
#include <stdio.h>
int add (int a, int b) { return a + b; }
int sub (int a, int b) { return a - b; }
int main()
{
int funcNumber;
int num1, num2;
int (*fp[2])(int, int);
fp[0] = add;
fp[1] = sub;
// 또는 int (*fp[2])(int, int) = {add, sub}; 로 선언과 초기화 가능
printf("함수 번호와 계산할 값을 입력하세요: ");
scanf("%d %d %d", &funcNumber, &num1, &num2);
printf(%d\n", fp[funcNumber](num1, num2));
return 0;
}
4. 구조체 멤버
#include <stdio.h>
struct Calc { int (*fp)(int, int); }; // 구조체가 함수를 포함하는 형태로 구현 가능
int add (int a, int b) { return a + b; }
int main()
{
struct Calc c;
c.fp = add;
printf("%d\n", c.fp(10, 20));
return 0;
}
5. 함수의 매개변수
#include <stdio.h>
int add (int a, int b) { return a + b; }
void calc(int (*fp)(int, int)) // 함수의 매개변수로 포인터 변수가 사용됨
{
printf("%d\n", fp(10, 20));
}
int main()
{
calc(add);
return 0;
}
함수 포인터 활용
1. qsort()
항 목 | 내 용 |
함수원형 | void qsort(void* base, size_t num, size_t size, int(*compar)(const void*, const void)); |
헤더 | stdlib.h |
기능 | 테이블의 자료를 퀵 정렬로 내림이나 오름차순으로 정렬 |
매개변수 | void* base : 테이블의 포인터 주소 size_t num : 테이블에 들어 있는 실제 데이터 갯수 size_t size : 한 개 요소의 크기 int(*compar)(const void*, const void) : 두 요소를 비교하기 위한 함수 포인터 |
반환값 | void |
구현 | 비교함수는 직접 구현해야 함 (배열의 자료형과 비교방식이 다르기 때문) |
예제
#include <stdio.h>
#include <stdlib.h>
int compare(const void* cmp1, const void* cmp2)
{
// 같으면 0을 반환, 다르다면 앞에가 크면 0보다 큰 값, 뒤에가 크면 0보다 작은 값을 반환
return strcmp((char*) cmp1, (char*) cmp2);
}
#define SIZE_TABLE 10
#define SIZE_ITEM 100
int main(void)
{
char table[SIZE_TABLE][SIZE_ITEM] =
{
"good", "hello", "hi", "morning", "computer", "GCC", "Programming"
};
int ndx;
for (ndx=0; ndx < SIZE_TABLE; ndx++)
printf("%s\n", table[ndx]);
printf("n정렬 후n");
qsort(table, SIZE_TABLE, SIZE_ITEM, compare);
for (ndx=0; ndx < SIZE_TABLE; ndx++)
printf("%s\n", table[ndx]);
return 0;
}
예제 2
#include <stdio.h>
#include <stdlib.h>
int values[] = { 40, 10, 100, 90, 20, 25 };
int compare (const void* a, const void* b)
{
return (*(int*)a - *(int*)b);
}
int main()
{
int n;
qsort(value, 6, sizeof(int), compare);
for (n=0; n<6; n++)
printf("%d ", values[n]);
return 0;
}
'프로그래밍 언어 공부 > C' 카테고리의 다른 글
파일 입출력 라이브러리(Basic Step) (0) | 2022.01.17 |
---|---|
도서관리 시스템 고도화(동적메모리) (0) | 2022.01.17 |
동적 메모리 (0) | 2022.01.15 |
수학 관련 라이브러리 (0) | 2022.01.13 |
도서관리 시스템 구현 (0) | 2022.01.13 |