C 기본 문법 – 포인터 – 2편: 포인터와 함수 완전 정복
안녕하세요, 여러분! 😊
오늘은 C 언어에서 포인터와 함수가 어떻게 짝꿍처럼 함께 동작하는지를 알아볼 시간이에요.
🧠 함수는 기본적으로 **값을 복사해서 전달(call by value)**하기 때문에,
함수 안에서 변수의 값을 변경해도 원본에는 영향을 주지 않아요!
그런데 포인터를 사용하면 원본 데이터를 직접 수정할 수 있답니다.
이건 마치 복사본이 아닌 실제 문서를 직접 수정하는 것과 같아요!
그럼 실전 예제와 함께 포인터와 함수의 환상적인 콤비를 배워볼까요? 😄
1. 함수 인자 전달 방식
기본 전달 방식: 값에 의한 전달 (Call by Value)
void change(int a) {
a = 100;
}
int main() {
int x = 10;
change(x);
printf("%d
", x); // 출력: 10
}
🧾
x
의 복사본이a
로 전달되기 때문에 원본x
는 변하지 않아요.
2. 포인터를 이용한 전달: 주소에 의한 전달 (Call by Reference)
void change(int *a) {
*a = 100;
}
int main() {
int x = 10;
change(&x);
printf("%d
", x); // 출력: 100
}
✅ 포인터로 전달하면 원본 값을 직접 수정할 수 있어요!
3. 함수에서 여러 값 반환하기
C는 return 하나밖에 못하죠? 그런데 포인터를 사용하면 여러 값을 반환하는 효과를 낼 수 있어요!
예시: 두 수를 더하고 곱한 결과를 반환
void calc(int a, int b, int *sum, int *prod) {
*sum = a + b;
*prod = a * b;
}
int main() {
int s, p;
calc(3, 4, &s, &p);
printf("합: %d, 곱: %d
", s, p); // 출력: 합: 7, 곱: 12
}
🎯 포인터를 사용하면 여러 개의 “결과 출력구”를 만들 수 있답니다!
4. 배열을 함수에 전달할 때
배열을 함수에 넘기면 자동으로 포인터처럼 동작해요.
void printArr(int *arr, int len) {
for (int i = 0; i < len; i++)
printf("%d ", arr[i]);
}
int main() {
int nums[4] = {1, 2, 3, 4};
printArr(nums, 4);
}
💡 배열은 항상 첫 번째 요소의 주소로 전달되므로 포인터 매개변수로 받습니다!
5. 문자열 함수도 결국 포인터 기반!
void printStr(char *str) {
while (*str) {
printf("%c", *str);
str++;
}
printf("
");
}
int main() {
char msg[] = "Hello!";
printStr(msg);
}
문자열은 문자 배열이므로 자연스럽게 포인터와 함께 쓰이는 구조에요 😊
6. 포인터를 반환하는 함수
함수에서 포인터를 반환할 수도 있어요!
하지만 지역 변수의 주소를 반환하면 위험하니 주의하세요!
❌ 위험한 예시
int* getAddress() {
int temp = 10;
return &temp; // 이 주소는 함수 끝나면 사라짐!
}
✅ 안전한 예시 (동적 메모리)
int* createArray(int n) {
return (int *)malloc(sizeof(int) * n);
}
📌 함수에서 malloc으로 메모리 할당한 뒤 포인터 반환하면 안전해요!
7. 함수 포인터 (심화 개념 맛보기)
int add(int a, int b) {
return a + b;
}
int main() {
int (*func)(int, int) = add;
printf("%d
", func(3, 5)); // 결과: 8
}
🎯 함수도 주소를 가질 수 있고, 포인터로 호출할 수 있어요!
이건 나중에 콜백 함수나 동적 호출에서 자주 쓰이니 살짝 기억만 해두세요 😊
✅ 포인터와 함수 요약 정리
패턴 | 설명 | 예시 |
---|---|---|
포인터로 값 수정 | 주소 전달 후 * 로 값 변경 |
change(&x); |
배열 전달 | 자동으로 포인터처럼 전달 | printArr(arr, len); |
여러 값 반환 | 포인터 매개변수 여러 개 | calc(a, b, &sum, &prod); |
포인터 반환 | malloc 등으로 메모리 생성 | return malloc(...); |
함수 포인터 | 함수 주소 저장 후 호출 | (*func)(x, y); |
⚠️ 포인터와 함수 사용 시 주의사항
주의점 | 설명 |
---|---|
지역 변수 주소 반환 금지 | 함수 종료 후 사라지는 주소 반환은 위험 |
포인터 초기화 | NULL 또는 유효한 주소로 초기화 후 사용 |
배열 크기 명시 | 포인터로 배열 받는 경우 크기 따로 전달 |
메모리 해제 | malloc으로 받은 포인터는 반드시 free() |
* 와 & 헷갈림 주의 |
* 는 값, & 는 주소입니다! |
마무리하며 💬
포인터와 함수의 조합은 함수로 데이터를 유연하게 처리하고 조작할 수 있는 강력한 무기예요!
포인터 없이 함수만 써서는 절대 할 수 없는 일들이 정말 많죠.
🎯 포인터는 “실물 주소를 들고 직접 찾아가는 메신저”,
함수는 “그 메신저에게 일을 시키는 명령 센터” 같아요.
이제 포인터와 함수가 어떻게 소통하는지 잘 이해되셨죠?
다음 시간에는 더 심화된 내용인 함수 포인터와 콜백 함수 등에 대해 다뤄볼게요!
질문이 있다면 언제든지 남겨주세요!
우리 함께 C 마스터 되자구요 💪😄