C 기본 문법 – 함수 – 3편: 함수 포인터 완전 정복
여러분 안녕하세요! 😊
오늘은 C 언어에서 한 단계 더 발전된 개념인 **함수 포인터(Function Pointer)**에 대해 공부해보겠습니다.
🧠 함수 포인터란?
말 그대로 함수의 주소를 저장하고, 그 주소를 통해 함수를 호출할 수 있게 해주는 포인터예요.
마치 “전화번호부”처럼, 전화번호(주소)를 통해 사람(함수)에 연결하는 방식이죠!
“함수를 변수처럼 다룬다고?”
“함수를 포인터로 전달한다고?”
처음엔 어렵게 느껴질 수 있지만, 비유와 예시를 통해 차근차근 풀어드릴게요!
1. 함수 포인터란 무엇인가요?
일반 포인터는 메모리 주소를 저장하는 변수죠?
함수 포인터는 그 중에서도 함수의 시작 주소를 저장하는 특별한 포인터입니다.
int add(int a, int b) {
return a + b;
}
위 함수는 메모리에 저장되고, 시작 주소가 존재해요.
이 주소를 변수처럼 저장해서 나중에 호출할 수 있습니다.
2. 함수 포인터 선언 방법
반환형 (*포인터이름)(매개변수목록);
예를 들어 int add(int, int)
를 가리키는 함수 포인터는 다음과 같이 선언합니다:
int (*fp)(int, int);
*fp
는 함수의 주소를 저장하고
(int, int)
는 함수의 매개변수 목록입니다.
3. 함수 포인터 사용 예제
기본 함수
int multiply(int a, int b) {
return a * b;
}
함수 포인터 선언 및 사용
int (*funcPtr)(int, int); // 함수 포인터 선언
funcPtr = multiply; // 주소 저장
int result = funcPtr(4, 5); // 포인터를 통해 함수 호출
printf("곱셈 결과: %d
", result); // 출력: 20
🎯
funcPtr(4, 5)
는multiply(4, 5)
와 같은 효과입니다!
4. 함수 포인터와 배열
함수 포인터를 배열 형태로 선언하면, 다양한 함수를 선택적으로 호출할 수 있어요!
예시: 간단한 계산기
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }
int divide(int a, int b) { return a / b; }
int (*ops[4])(int, int) = { add, sub, mul, divide };
int main() {
int x = 20, y = 5;
printf("덧셈: %d
", ops[0](x, y)); // add
printf("뺄셈: %d
", ops[1](x, y)); // sub
printf("곱셈: %d
", ops[2](x, y)); // mul
printf("나눗셈: %d
", ops[3](x, y)); // divide
return 0;
}
🎯 배열을 이용하면 함수 호출을 동적으로 선택할 수 있어요!
5. 함수 포인터를 인자로 전달하기
함수를 다른 함수에 인자로 넘길 수 있다면 어떨까요?
바로 그게 함수 포인터의 강력한 기능입니다!
예제: 연산자 전달 함수
int compute(int a, int b, int (*op)(int, int)) {
return op(a, b);
}
int add(int x, int y) { return x + y; }
int mul(int x, int y) { return x * y; }
int main() {
printf("5 + 3 = %d
", compute(5, 3, add));
printf("5 * 3 = %d
", compute(5, 3, mul));
return 0;
}
🎯 마치 “전략 전달”처럼 원하는 기능을 넘겨줄 수 있어요!
6. typedef로 함수 포인터를 간단하게
함수 포인터 문법은 헷갈리기 쉬워요.
그래서 **typedef
를 이용해서 별칭(alias)**을 만들면 훨씬 읽기 쉽습니다!
예제
typedef int (*CalcFunc)(int, int);
int sub(int a, int b) {
return a - b;
}
int main() {
CalcFunc func = sub;
printf("10 - 4 = %d
", func(10, 4));
return 0;
}
7. 함수 포인터와 콜백 함수
함수 포인터는 콜백(callback) 함수 개념과 매우 밀접합니다.
콜백 함수란, 특정 이벤트가 발생했을 때 미리 등록된 함수를 호출하는 방식입니다.
예제: 문자열 처리 콜백
void runCallback(void (*callback)()) {
printf("작업 시작
");
callback();
printf("작업 종료
");
}
void sayHello() {
printf("안녕하세요!
");
}
int main() {
runCallback(sayHello); // sayHello를 콜백으로 전달
return 0;
}
🎯 GUI 이벤트, 타이머 처리, 정렬 기준 함수 등에서 자주 활용됩니다!
✅ 함수 포인터 요약표
문법 요소 | 예시 | 설명 |
---|---|---|
함수 포인터 선언 | int (*fp)(int, int); |
int 반환, int 2개 받는 함수 |
함수 주소 저장 | fp = add; |
함수 이름만 써도 주소 저장 |
함수 호출 | fp(3, 4); |
add(3, 4); 와 동일 |
함수 포인터 배열 | fp[4] |
다양한 함수 담기 |
함수 인자로 전달 | compute(a, b, add); |
동적 기능 처리 가능 |
typedef 사용 | typedef int (*FUNC)(int, int); |
코드 가독성 향상 |
⚠️ 함수 포인터 사용 시 주의사항
주의사항 | 설명 |
---|---|
매개변수와 반환형 정확히 일치해야 함 | 예: int (*f)(int, int) 형태의 함수만 할당 가능 |
null 포인터 체크 필수 | 잘못된 주소 접근은 프로그램 다운 |
함수 이름만으로 주소 전달됨 | &add 대신 add 만 써도 OK |
문법이 복잡하므로 typedef 적극 활용 | 가독성을 높이기 위해 typedef 사용 권장 |
마무리하며 💬
함수 포인터는 C 언어에서 고급 기능에 속하지만,
이 개념을 잘 활용하면 더 유연하고 구조적인 프로그램을 만들 수 있어요!
🎯 마치 “리모컨”처럼, 어떤 함수든 버튼 하나로 호출할 수 있는 방식!
전자제품처럼 모듈화된 기능을 함수 포인터로 조립해보세요 🔧
다음 편에서는 함수 포인터를 활용한 정렬 기준 함수 전달이나
메모리 관련 고급 활용도 다뤄볼게요.
궁금한 부분이 있다면 언제든지 질문 주세요!
C 언어 마스터까지, 함께 달려봅시다! 💻🔥