Search
moon
sun
✅

Call By Value, Call By Reference

함수가 인자를 넘기는 방식의 차이

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
복사