C언어) 포인터 - 함수 포인터

Lapis0875·2022년 10월 21일
0

c언어

목록 보기
5/21
post-thumbnail

📑포인터 시리즈

포인터 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>, ...)
  • 제일 앞 return-type은 함수의 반환형을 적어요.
  • name 에는 포인터 변수의 이름을 적어요. 이 이름은 반드시 소괄호로 감싸져야 해요
  • 이름 뒤의 소괄호 안에는 함수의 인자별 타입을 적어요. 앞선 calculate의 경우, sum과 mul 모두 int형 인자 2개를 받았기 때문에 (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

배운 내용들을 정리해보고 있어요. 잘못 기재된 내용이 있다면, 댓글로 지적해주시면 수정할게요.

profile
새내기 대학생 개발자에요 :D

0개의 댓글