산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> C 언어

C 함수 포인터: 실전 예제와 모범 사례

함수 포인터는 C에서 강력한 기능을 열어줍니다. 값 복사 대신 메모리 주소를 통해 함수가 데이터를 직접 조작하게 하여, 제자리 스와핑, 동적 콜백, 고차 함수 같은 패턴을 가능하게 합니다.

함수 포인터 예제

고전적인 스왑 루틴은 함수가 두 변수의 주소로 연산하여 값을 교환하는 방법을 보여줍니다.

void swap (int *a, int *b);
int main() {
    int m = 25;
    int n = 100;
    printf("m is %d, n is %d\n", m, n);
    swap(&m, &n);
    printf("m is %d, n is %d\n", m, n);
    return 0;
}
void swap (int *a, int *b) {
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

출력:

m is 25, n is 100
m is 100, n is 25

C 함수 포인터: 실전 예제와 모범 사례

  1. 두 정수 포인터로 swap 선언
  2. main에서 m, n 초기화 후 출력
  3. swap(&m, &n) 호출로 주소 전달
  4. swap 내부에서 임시 변수로 값 교환
  5. 포인터 역참조로 실제 데이터 읽기/쓰기

배열 매개변수를 가진 함수

배열은 함수에 전달될 때 포인터로 붕괴(decay)됩니다. 다음 프로그램은 포인터를 순회하며 배열 요소 합계를 구합니다.

int add_array (int *a, int num_elements);
int main() {
    int Tab[5] = {100, 220, 37, 16, 98};
    printf("Total summation is %d\n", add_array(Tab, 5));
    return 0;
}
int add_array (int *p, int size) {
    int total = 0;
    for (int k = 0; k < size; k++) {
        total += p[k]; /* total += *p; p++; 와 동등 */
    }
    return total;
}

출력:

Total summation is 471

C 함수 포인터: 실전 예제와 모범 사례

  1. add_array를 포인터와 크기 받아 합계 반환하도록 정의
  2. 배열 이름 Tab(포인터로 붕괴)과 길이를 함수에 전달

배열을 반환하는 함수

함수는 정적 배열에 대한 포인터를 반환할 수 있습니다. 호출자가 메모리 할당 관리 없이 임시 배열이 필요할 때 유용합니다.

#include <stdio.h>
int * build_array();
int main() {
    int *a;
    a = build_array(); /* 처음 5개 짝수 얻기 */
    for (int k = 0; k < 5; k++)
        printf("%d\n", a[k]);
    return 0;
}
int * build_array() {
    static int Tab[5] = {1,2,3,4,5};
    return Tab;
}

출력:

1
2
3
4
5

C 함수 포인터: 실전 예제와 모범 사례

  1. 정적 배열 포인터 반환 함수 선언
  2. 반환된 포인터로 배열 내용 순회 및 출력

함수 포인터(Function Pointers)

함수 포인터는 함수의 진입점 주소를 담아 동적 디스패치와 콜백을 가능하게 합니다. 선언 문법은 별표 주위에 괄호가 필요하여 잘못된 해석을 방지합니다.

반환_타입 (*함수_이름)(인수들)

예제: 포인터를 통해 루틴 호출.

#include <stdio.h>
void Hi_function (int times); /* 함수 */
int main() {
    void (*function_ptr)(int); /* 함수 포인터 */
    function_ptr = Hi_function; /* 대입 */
    function_ptr(3); /* 호출 */
    return 0;
}
void Hi_function (int times) {
    for (int k = 0; k < times; k++)
        printf("Hi\n");
}

출력:

Hi
Hi
Hi

C 함수 포인터: 실전 예제와 모범 사례

  1. 일반 함수 정의
  2. 올바른 시그니처로 함수 포인터 선언
  3. 포인터에 함수 이름 대입
  4. 포인터 통해 함수 호출

함수 포인터 배열(Array of Function Pointers)

여러 함수 포인터를 배열에 저장하면 switch 문과 유사한 테이블 기반 접근이 가능합니다. 다음 프로그램은 간단한 계산기를 보여줍니다.

#include <stdio.h>
int sum(int num1, int num2);
int sub(int num1, int num2);
int mult(int num1, int num2);
int divi(int num1, int num2);
int main() {
    int x, y, choice, result;
    int (*ope[4])(int, int);
    ope[0] = sum;
    ope[1] = sub;
    ope[2] = mult;
    ope[3] = divi;
    printf("Enter two integer numbers: ");
    scanf("%d%d", &x, &y);
    printf("Enter 0 to sum, 1 to subtract, 2 to multiply, or 3 to divide: ");
    scanf("%d", &choice);
    result = ope[choice](x, y);
    printf("%d", result);
    return 0;
}
int sum(int x, int y) {return x + y;}
int sub(int x, int y) {return x - y;}
int mult(int x, int y) {return x * y;}
int divi(int x, int y) {return y != 0 ? x / y : 0;}

결과: 13 48 2 입력 → 624

C 함수 포인터: 실전 예제와 모범 사례

  1. 네 가지 산술 함수 정의
  2. 일치하는 시그니처의 함수 포인터 4개 배열 생성
  3. 각 포인터에 해당 함수 대입
  4. 사용자 선택 받아 선택된 함수 호출

Void 포인터를 사용하는 함수

Void 포인터는 타입 불가지론적 데이터 접근을 제공합니다. 함수 매개변수로 쓰이면 호출자가 올바른 캐스팅을 제공하는 한 모든 데이터 타입을 받을 수 있습니다.

void * cube (const void *);

예제 프로그램:

#include <stdio.h>
void* cube (const void* num);
int main() {
    int x = 4;
    int cube_int = (int)cube(&x);
    printf("%d cubed is %d\n", x, cube_int);
    return 0;
}
void* cube (const void *num) {
    int result = (*(int *)num) * (*(int *)num) * (*(int *)num);
    return (void*)result;
}

결과: 4 cubed is 64

C 함수 포인터: 실전 예제와 모범 사례

  1. const void 포인터를 받아 void 포인터 반환하는 함수 정의
  2. 포인터를 int *로 캐스팅하여 값 접근
  3. 세제곱 계산 후 결과를 void *로 캐스팅해 반환

인수로 전달되는 함수 포인터

함수 포인터를 다른 함수에 전달하는 것은 콜백의 일반적인 패턴입니다. 표준 라이브러리 qsort가 이 기법을 사용하여 임의 타입 배열을 정렬합니다.

void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *));

정수 배열 정렬 예제:

#include <stdio.h>
#include <stdlib.h>
int compare (const void *, const void *);
int main() {
    int arr[5] = {52, 14, 50, 48, 13};
    size_t num = sizeof(arr)/sizeof(arr[0]);
    size_t width = sizeof(arr[0]);
    qsort((void *)arr, num, width, compare);
    for (size_t i = 0; i < num; i++)
        printf("%d ", arr[i]);
    return 0;
}
int compare (const void *elem1, const void *elem2) {
    int a = *(int *)elem1;
    int b = *(int *)elem2;
    return (a - b);
}

결과: 13 14 48 50 52

C 함수 포인터: 실전 예제와 모범 사례

  1. compare 구현: 두 정수 비교해 음수/0/양수 반환
  2. sizeof로 배열 크기와 요소 너비 결정
  3. 배열, 개수, 너비, 비교 함수로 qsort 호출
  4. 정렬된 배열 출력으로 검증

C 언어

  1. C 사용자 정의 함수 4가지 검증된 패턴
  2. C++ do-while 루프: 문법, 실전 예제, 중첩 루프
  3. C++ 포인터 완전 정복: 개념, 예제, 실전 활용
  4. C++ 연산자 오버로딩 실전 가이드: 문법, 접근법, 코드 예제
  5. C++ 함수 완전 정복: 실전 코드 예제로 이해하기
  6. C# 컬렉션(Collections) 마스터하기: 실전 예제로 배우는 유연한 데이터 관리
  7. C 포인터 완벽 가이드: 타입, 사용법, 모범 사례
  8. Python str.count() 마스터하기: 문자 및 부분문자열 개수 세기 예제
  9. 파이썬 람다 함수 마스터하기: 실용 예제 & 모범 사례
  10. 파이썬 round() 함수 완전 정복: 실용 예제로 이해하기