C 언어는 다형성(polymorphism)을 지원하지 않는다는 점에서 객체 지향 프로그래밍 언어와는 조금 다릅니다. 그러나 C 언어에서도 다형성과 비슷한 효과를 내기 위해 여러 가지 기법을 사용할 수 있습니다. 이 포스트에서는 C 언어에서의 다형성을 구현하는 몇 가지 일반적인 방법과 그에 대한 예제를 살펴보겠습니다.
함수 포인터 활용
C 언어에서 다형성을 구현하는 한 가지 방법은 함수 포인터(function pointer)를 사용하는 것입니다. 함수 포인터를 이용하면 실행 시간에 어떤 함수를 호출할지 결정할 수 있습니다. 아래는 간단한 예제 코드입니다.
#include <stdio.h>
void add_int(int a, int b) {
printf("Sum: %d\n", a + b);
}
void add_float(float a, float b) {
printf("Sum: %f\n", a + b);
}
int main() {
void (*addPtr)(int, int);
addPtr = &add_int;
addPtr(1, 2);
addPtr = &add_float;
addPtr(1.5, 2.5);
return 0;
}
위 코드에서 addPtr
은 int
형식의 매개변수를 가지는 add_int
함수와 float
형식의 매개변수를 가지는 add_float
함수를 가리킬 수 있습니다.
구조체와 함수 조합
또 다른 방법은 구조체(struct)와 함수 포인터를 조합하는 것입니다. 아래는 구조체를 활용한 다형성의 예제입니다.
#include <stdio.h>
typedef struct {
void (*speak)();
} Animal;
void dog_speak() {
printf("Woof!\n");
}
void cat_speak() {
printf("Meow!\n");
}
int main() {
Animal dog;
dog.speak = &dog_speak;
dog.speak();
Animal cat;
cat.speak = &cat_speak;
cat.speak();
return 0;
}
위 코드에서 Animal
구조체는 speak
함수 포인터를 멤버로 가지고 있습니다. 이를 통해 각 Animal
객체가 서로 다른 speak
함수를 가리킬 수 있게 됩니다.
함수 포인터 배열
마지막으로, 함수 포인터 배열을 사용하여 다형성을 구현할 수도 있습니다. 아래는 함수 포인터 배열을 활용한 예제입니다.
#include <stdio.h>
void print_int(int num) {
printf("Integer: %d\n", num);
}
void print_float(float num) {
printf("Float: %f\n", num);
}
int main() {
void (*printers[2])(int);
printers[0] = &print_int;
printers[1] = (void (*)(int)) &print_float;
int num = 10;
float fnum = 3.14;
printers[0](num);
printers[1]((int)fnum);
return 0;
}
위 코드에서 printers
배열은 각각 int
형식과 float
형식을 출력하는 함수를 가리킬 수 있습니다.
이처럼 C 언어에서도 함수 포인터를 활용하여 간접적으로 다형성을 구현할 수 있습니다. 하지만 이러한 방식은 명확하지 않거나 실수하기 쉽다는 단점이 있으므로 주의하여 사용해야 합니다.
결론
C 언어는 명시적으로는 다형성을 지원하지 않지만, 함수 포인터를 활용하여 유사한 효과를 낼 수 있습니다. 이러한 기법을 사용하면 코드 재사용성과 유연성을 높일 수 있으며, 객체 지향 프로그래밍의 특성을 어느 정도 살릴 수 있습니다.
참고 문헌:
- https://www.geeksforgeeks.org/function-pointer-in-c/
- https://www.programiz.com/c-programming/c-structures-pointers