티스토리 뷰
반응형
C언어 기초 Chapter 19: 함수 포인터와 void 포인터
19-1. 함수 포인터와 void 포인터
함수 포인터란?
- 함수의 주소를 저장하는 포인터 변수
- 함수도 메모리에 올라가기 때문에 시작 주소가 존재
- 이를 이용해 함수를 변수처럼 전달하거나 동적으로 호출할 수 있음
기본 문법
반환형 (*포인터이름)(매개변수목록);
예제: 함수 포인터 선언과 사용
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main(void) {
int (*fp)(int, int); // 함수 포인터 선언
fp = add; // 함수 주소 저장
int result = fp(3, 4); // 함수 포인터로 호출
printf("결과 = %d\n", result);
return 0;
}
👉 출력: 결과 = 7
함수 포인터를 인자로 전달
#include <stdio.h>
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
void calc(int (*op)(int, int), int x, int y) {
printf("결과: %d\n", op(x, y));
}
int main(void) {
calc(add, 10, 5); // 덧셈
calc(sub, 10, 5); // 뺄셈
return 0;
}
👉 출력:
결과: 15
결과: 5
void 포인터란?
- 자료형이 정해지지 않은 포인터
- 어떤 타입의 주소든 담을 수 있음
- 하지만 사용하려면 반드시 형 변환(cast) 필요
#include <stdio.h>
int main(void) {
int a = 10;
double d = 3.14;
void *vp; // void 포인터
vp = &a;
printf("정수값 = %d\n", *(int *)vp);
vp = &d;
printf("실수값 = %.2f\n", *(double *)vp);
return 0;
}
👉 출력:
정수값 = 10
실수값 = 3.14
⚠️ 주의: void * 는 직접 산술 연산(vp+1) 불가능 → 형변환 후 사용해야 함
19-2. main 함수와의 연결성
- C 프로그램은 main 함수에서 시작
- main 함수도 함수 포인터로 가리킬 수 있음
- 프로그램 구조 설계 시 콜백(callback) 개념 구현 가능
예제 (간단한 콜백):
#include <stdio.h>
void hello() { printf("Hello, World!\n"); }
void run(void (*func)()) {
func(); // 전달된 함수 실행
}
int main(void) {
run(hello); // 함수 포인터로 전달
return 0;
}
👉 출력: Hello, World!
핵심 정리 ✅
- 함수 포인터: 함수 주소 저장 및 호출 가능, 콜백 구현에 활용
- void 포인터: 모든 타입 주소 저장 가능, 반드시 형 변환 필요
- 함수 포인터와 void 포인터는 C언어에서 유연한 코드 작성의 핵심
연습 문제 ✍️
- 두 정수를 곱하는 mul 함수를 작성하고, 함수 포인터를 통해 호출해 보세요.
- 두 개의 함수(덧셈, 나눗셈)를 준비하고, 사용자 선택에 따라 다른 함수를 실행하는 프로그램을 작성하세요.
- void 포인터를 이용해 정수와 실수를 하나의 배열처럼 번갈아 출력하는 프로그램을 작성하세요.
👉 연습문제 정답은? ▼
Chapter 19 연습문제 풀이
1) 두 정수를 곱하는 mul 함수를 작성하고, 함수 포인터를 통해 호출하기
#include <stdio.h>
int mul(int a, int b) {
return a * b;
}
int main(void) {
int (*fp)(int, int); // 함수 포인터 선언
fp = mul; // mul 함수 주소 저장
int result = fp(3, 4); // 함수 포인터로 호출
printf("3 * 4 = %d\n", result);
return 0;
}
👉 출력:
3 * 4 = 12
2) 사용자 선택에 따라 다른 함수 실행 (덧셈 / 나눗셈)
#include <stdio.h>
int add(int a, int b) { return a + b; }
int divide(int a, int b) { return b != 0 ? a / b : 0; }
int main(void) {
int choice, x, y;
int (*op)(int, int);
printf("연산 선택 (1: 덧셈, 2: 나눗셈): ");
scanf("%d", &choice);
printf("두 정수 입력: ");
scanf("%d %d", &x, &y);
if (choice == 1) op = add;
else op = divide;
printf("결과 = %d\n", op(x, y));
return 0;
}
👉 실행 예시
연산 선택 (1: 덧셈, 2: 나눗셈): 1
두 정수 입력: 6 4
결과 = 10
연산 선택 (1: 덧셈, 2: 나눗셈): 2
두 정수 입력: 8 2
결과 = 4
3) void 포인터를 이용해 정수와 실수를 번갈아 출력하기
#include <stdio.h>
int main(void) {
int a = 10, b = 20;
double x = 3.14, y = 2.71;
void *arr[4]; // void 포인터 배열
arr[0] = &a;
arr[1] = &x;
arr[2] = &b;
arr[3] = &y;
printf("정수1 = %d\n", *(int *)arr[0]);
printf("실수1 = %.2f\n", *(double *)arr[1]);
printf("정수2 = %d\n", *(int *)arr[2]);
printf("실수2 = %.2f\n", *(double *)arr[3]);
return 0;
}
👉 출력:
정수1 = 10
실수1 = 3.14
정수2 = 20
실수2 = 2.71
핵심 정리 ✅
- 함수 포인터를 이용하면 함수를 변수처럼 다룰 수 있다.
- 조건에 따라 다른 함수를 실행하는 동적 호출 가능하다.
- void 포인터는 여러 타입을 하나의 배열에 섞어 담을 때 유용하다.
반응형
'[문법] C언어' 카테고리의 다른 글
11) C언어 다차원 배열과 포인터 완전정리: 2차원 배열부터 포인터까지 (2) | 2025.09.02 |
---|---|
10) C언어 포인터의 포인터: 이중 포인터 개념, 함수 활용, 동적 메모리 할당 (0) | 2025.09.02 |
9) C언어 포인터와 함수: 배열 전달, Call by Value vs Reference, const 정리 (2) | 2025.09.01 |
8) C언어 포인터와 배열 완전정리: 관계, 연산, 문자열, 포인터 배열 (2) | 2025.09.01 |
7) C언어의 1차원 배열과 포인터에 대해 알아보자 (2) | 2025.09.01 |