포인터 5부작의 마지막이에요. 지난 4개의 글을 읽었거나, 이미 알고계신게 아니라면 이 시리즈의 지난 글들도 읽어주세요 😉
함수도 포인터로 가리키고, 인자로 전달할 수 있어요.
int형 값을 2개 받아, 그 합, 곱을 반환하는 간단한 함수 2개를 작성했어요.
int sum(int a, int b)
{
return a + b;
}
int mul(int a, int b)
{
return a * b;
}
이제, 위 두 함수를 가리킬 수 있는 함수 포인터를 선언해볼게요.
int (*calculate)(int, int);
함수 포인터는 아래와 같은 구조로 선언해요.
<return-type> (*name)(<arg1-type>, <arg2-type>, ...)
(int, int)
로 작성했어요.이제, 함수 포인터에 직접 함수를 할당하고 사용해볼게요.
int a = 10, b = 5;
calculate = sum;
printf("%d + %d = %d\n", a, b, calculate(a, b));
calculate = mul;
printf("%d * %d = %d\n", a, b, calculate(a, b));
10 + 5 = 15
10 * 5 = 50
함수형 프로그래밍 패러다임을 보면, 함수를 다른 함수의 인자에 전달하곤 해요. 대표적으로 map, filter, reduce 등이 함수를 인자로 받아 사용해요. C언어에서도 함수 포인터를 사용하면 비슷하게 구현할 수 있지 않을까 생각해요.
stdlib.h 라이브러리에는 qsort
라는 함수가 제공돼요.
void qsort(void *array, size_t n_els, size_t el_size, int (*compare)(const void *, const void *));
qsort를 사용하는 예제를 보면서, 함수 포인터를 어떻게 활용할 수 있는지 알아볼게요. 간단하게 길이 10짜리 배열을 qsort 함수를 사용해 정렬해보는 예제에요.
#include <stdio.h>
#include <stdlib.h>
#define N 10 // 배열의 길이를 상수로 정의해둘게요.
int compare(const void *, const void *);
void print_array(int size, int array[size]);
int main(void)
{
int s[N] = {3, 2, 1, 5, 7, 6, 8, 9, 4, 0}; // 정렬하기 위한 배열이에요.
print_array(N, s); // 정렬 전 상태를 확인해요.
qsort(s, N, sizeof(int), compare); // compare 함수를 사용해, 배열 s를 정렬해요.
print_array(N, s); // 정렬 후 상태를 확인해요.
return 0;
}
/**
* @brief qsort에서 사용할, 두 수를 비교하는 함수에요.
*
* @param a 비교할 값이에요.
* @param b 비교할 값이에요.
* @return int 비교할 결과에요. a > b일때는 1, a < b일때는 -1, a == b일때는 0을 반환해요.
*/
int compare(const void *a, const void *b)
{
// 함수의 인자를 const void * 형으로 받기 위해, 먼저 비교하고자 하는 자료형으로 형변환 해줘야 해요.
int ia = *(int*) a;
int ib = *(int*) b;
// 비교한 결과를 반환해요.
if (ia > ib)
return 1;
else if (ia < ib)
return -1;
else
return 0;
}
/**
* @brief 배열의 요소를 한 줄로 출력해요.
*
* @param size 배열의 길이에요.
* @param array 배열이에요.
*/
void print_array(int size, int array[size])
{
for (int i = 0; i < size; i++)
{
printf("%d", array[i]);
if (i < size - 1)
printf(" ");
}
printf("\n");
}
실행 결과는 아래와 같아요.
3 2 1 5 7 6 8 9 4 0
0 1 2 3 4 5 6 7 8 9
배운 내용들을 정리해보고 있어요. 잘못 기재된 내용이 있다면, 댓글로 지적해주시면 수정할게요.