C의 함수 포인터

Jinku Hu 2023년10월12일
  1. void (*func)()표기법을 사용하여 C에서 함수 포인터 정의
  2. 함수 포인터 배열을 사용하여 유형 일반 프로그래밍 기능 구현
C의 함수 포인터

이 기사에서는 C에서 함수 포인터를 사용하는 방법을 소개합니다.

void (*func)()표기법을 사용하여 C에서 함수 포인터 정의

함수 포인터는 동적 함수 호출, 객체 지향 디자인과 유사한 자체 메서드를 포함하는 구조, 유형 제네릭 프로그래밍 등과 같은 고급 기능을 구현하는 C 프로그래밍의 또 다른 구조입니다. 함수 포인터 선언은 복잡한 구문을 가질 수 있습니다. void (*func)(void)표기법은 매개 변수가없는void 함수에 대한 포인터를 선언합니다. printInt 함수의 주소를 할당했지만 다음 예제에서는void (*func)(void)유형 함수 포인터에 단일int 인수를 사용합니다. func라는 함수 포인터가 정의되면 일반적인 함수 호출 표기법 func(arg)또는 역 참조 연산자 (*func)(arg)를 사용하여 호출 할 수 있습니다.

#include <stdio.h>
#include <stdlib.h>

void printInt(int x) { printf("printed from printInt: %d\n", x); }

int main() {
  int input1 = 10233;

  void (*func)(int) = printInt;

  func(input1);
  (*func)(input1);

  exit(EXIT_SUCCESS);
}

출력:

printed from printInt: 10233
printed from printDouble: 11.234000

또는typedef를 사용하여 함수 포인터의 새로운 유형 별칭을 정의하여 코드를 더 읽기 쉽게 만들 수 있습니다. 다른 함수 유형에는 별도의typedef 문이 필요합니다. 다음 코드 샘플에서는 인수없이 void 함수에 대한 포인터를 정의합니다. 그럼에도 불구하고printIntprintDouble 함수 주소는 모두FuncPtr 유형의 변수에 저장됩니다. 특정 함수의 주소는 다음 예에서 설명한 것처럼 명시적인 & 연산자 또는 함수 이름 자체의 암묵적 할당으로 취할 수 있다는 점에 유의해야 한다.

#include <stdio.h>
#include <stdlib.h>

typedef void (*FuncPtr)();

void printInt(int x) { printf("printed from printInt: %d\n", x); }

void printDouble(double x) { printf("printed from printDouble: %f\n", x); }

int main() {
  int input1 = 10233;
  double input2 = 11.234;

  FuncPtr func1 = printInt;
  FuncPtr func2 = printDouble;

  func1(input1);
  func2(input2);

  exit(EXIT_SUCCESS);
}

출력:

printed from printInt: 10233
printed from printDouble: 11.234000

함수 포인터 배열을 사용하여 유형 일반 프로그래밍 기능 구현

다른 객체와 마찬가지로 괄호 []표기법으로 함수 포인터 배열을 정의 할 수 있습니다. 이 어레이는 런타임 중에 특정 기능을 쉽게 선택하고 호출하는 데 사용할 수 있습니다. 사용자가 제어 표현식의 유형 평가에 따라 특정 케이스 기반을 선택할 수있는 표현식과 같은switch_Generic 키워드를 사용하고 있습니다. 결과적으로 우리는 switch조건에서 전달 된 변수의 유형에 따라 해당하는 print함수가 호출되는 다음 코드 예제를 구현합니다. enum유형은 다양한 경우에 대한 상수 값을 정의하는데도 사용됩니다.

#include <stdio.h>
#include <stdlib.h>

enum TYPE { INTEGER, DOUBLE, INVALID };

#define typename(x) \
  _Generic((x), int: INTEGER, double: DOUBLE, default: INVALID)

typedef void (*FuncPtr)();

void printInt(int x) { printf("printed from printInt: %d\n", x); }

void printDouble(double x) { printf("printed from printDouble: %f\n", x); }

int main() {
  int input1 = 10233;
  double input2 = 11.234;

  FuncPtr func_ptrs[] = {printInt, printDouble};

  switch (typename(input1)) {
    case INTEGER:
      func_ptrs[INTEGER](input1);
      break;
    case DOUBLE:
      func_ptrs[DOUBLE](input1);
      break;
    case INVALID:
      printf("No corresponding type found!\n");
    default:
      break;
  }

  switch (typename(input2)) {
    case INTEGER:
      func_ptrs[INTEGER](input2);
      break;
    case DOUBLE:
      func_ptrs[DOUBLE](input2);
      break;
    case INVALID:
      printf("No corresponding type found!\n");
    default:
      break;
  }

  exit(EXIT_SUCCESS);
}

출력:

printed from printInt: 10233
printed from printDouble: 11.234000
작가: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

관련 문장 - C Pointer