함수가 인자를 넘기는 방식의 차이
Call By Value(값에 의한 호출)
•
실제 값의 복사본이 함수로 전달
•
함수 안에서 매개변수를 수정해도, 원본 변수에는 영향 X
코드
#include <stdio.h>
void modifyValue(int x) {
x = 100; // 복사본만 변경
}
int main() {
int a = 10;
modifyValue(a);
printf("a: %d\n", a); // 여전히 10
return 0;
}
C
복사
특징
•
원본이 변경되지 않아 안전
•
큰 구조체를 인자에 전달하면 메모리 복사가 많아져 성능 저하 가능
Call By Reference(참조에 의한 호출)
•
변수의 주소를 함수로 전달
•
함수 안에서 해당 주소를 이용해 원본 데이터를 변경 가능
코드
#include <stdio.h>
void modifyValue(int *x) {
*x = 100; // 원본 변경
}
int main() {
int a = 10;
modifyValue(&a);
printf("a: %d\n", a); // 100으로 변경됨
return 0;
}
C
복사
특징
•
원본 변경 가능(포인터 사용)
•
불필요한 데이터 복사가 없어서 성능 향상
•
원본이 쉽게 바뀌므로, 의도치 않은 버그 위험도 증가
헷갈릴만한 포인트) 포인터를 써도 Call By Value처럼 동작하는 경우
•
C에는 진짜 Call By Reference는 없고, 항상 값에 의한 호출(Call By Value)만 존재
◦
포인터를 쓴다고 해도 함수가 참조 자체를 받는 것이 아니라, 포인터 변수의 값(주소)를 복사해서 받는 것
◦
C에는 참조 타입이 없으므로, Call By Reference처럼 보이는 건 사실 포인터를 이용한 Call By Value
즉, 주소라는 값을 넘기는 것
예시 - 포인터를 써도 원본이 안 바뀌는 경우
#include <stdio.h>
void changePointer(int *p) {
int temp = 200;
p = &temp; // p가 가리키는 대상을 변경 (복사본에만 영향)
}
int main() {
int a = 10;
int *ptr = &a;
changePointer(ptr);
*ptr = 300; // main의 ptr은 여전히 a를 가리킴
printf("a: %d\n", a); // 300
return 0;
}
C
복사
포인터 자체를 변경하려면, 이중 포인터가 필요!
#include <stdio.h>
void changePointer(int **pp) {
static int x = 500;
*pp = &x; // 원본 포인터가 가리키는 주소 변경
}
int main() {
int a = 10;
int *ptr = &a;
changePointer(&ptr);
printf("a: %d\n", a); // a값은 여전히 10
printf("*ptr : %d\n", *ptr); // ptr은 x를 가리키므로 값이 500
return 0;
}
C
복사
