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
함수에 대한 포인터를 정의합니다. 그럼에도 불구하고printInt
와printDouble
함수 주소는 모두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
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