Back to all posts
Call by value vs Call by reference
Written by ppotatoG & Posted on July 26th, 2023
Call by value vs Call by reference in C
Call by value
값에 의한 호출
함수 호출 시 넘기는 인자의 값이 매개변수에 복사
되는 것을 값에 의한 호출
이라고 한다.
이 방법은 함수 내에서 매개변수의 값에 어떤 조작을 가하더라도 원래 변수에는 전혀 영향을 주지 않는다.
이를 통해 함수 내부에서의 로직 처리가 외부의 변수에 영향을 미치지 않도록
할 수 있다.
#include <stdio.h>void call_by_value(int x) {x = 100;}int main() {int a = 10;call_by_value(a);printf("%d\n", a); // Outputs: 10return 0;}
call_by_value 함수 내에서 변수 x의 값을 변경해도 원본 변수 a의 값은 변경되지 않는다.
왜냐하면, 함수 호출 시 a의 값이 x로 복사
되었기 때문.
Call by reference
참조에 의한 호출
Call by reference도 인자의 값이 매개변수에 복사(Copy)된다는 점은 동일하다.
다만, 참조에 의한 호출에서는 변수의 주소값이 매개변수로 넘어
가게 된다.
따라서, 함수 내에서 이 매개변수를 통해 직접 변수의 값을 변경할 수 있다
.
#include <stdio.h>void call_by_reference(int *x) {*x = 100;}int main() {int a = 10;call_by_reference(&a);printf("%d\n", a); // Outputs: 100return 0;}
call_by_reference 함수를 호출할 때 a의 주소값이 넘어가게 되며, 함수 내에서 이 주소에 해당하는 값이 직접 변경 된다.
결과적으로, 원본 변수 a의 값이 변경
.
Call by Value | Call by Reference | |
---|---|---|
정의 | 함수에 값을 복사해서 전달. 복사된 값이 변경되어도 원래 값에는 영향을 주지 않음. | 함수에 값의 참조 (주소)를 전달. 함수 내에서 참조가 가리키는 값이 변경되면 원래 값도 변경. |
사용 경우 | 값을 보호하고, 함수 내부에서 원래 값의 변경 없이 그 값을 사용하고 싶을 때 사용. | 원래 값에 대한 변경이 필요하거나, 대용량 데이터를 효율적으로 처리하고 싶을 때 사용. |
Deep Copy vs Shallow Copy in JavaScript
JavaScript 의 shallow copy, deep copy 와 C의 Call by value, Call by reference 는 조금 다른 의미를 가진다.
Deep copy
원본 객체의 값을 복사하여 완전히 새로운 객체를 생성
하는것을 뜻한다.
원본 객체와 복사된 객체는 서로 다른 메모리를 가지며, 둘 중 하나를 변경해도 다른 하나에는 영향을 미치지 않는다
.
const object = {0: 'a', 1: 'b'}const b = JSON.parse(JSON.stringify(object))b[0] = 0object[0] // 'a'object[0] = 'c'b[0] // 0
또한 React와 같은 프레임워크 또는 라이브러리에서 상태의 불변성을 유지
할 때 자주 사용된다.
상태 객체를 직접 수정하지 않고 새로운 객체를 생성하여 수정한 후 상태를 갱신한다.
const [state, setState] = useState({count: 0})setState(prev => ({...prev, count: prev.count + 1}))
깊은복사를 하는 방법
const object = {0: 'a', 1: 'b'}const a = JSON.parse(JSON.stringify(object))
const object = {0: 'a', 1: 'b'}const a = _.cloneDeep(object)
Shallow copy
원본 객체의 주소값을 참조하는 객체를 생성
하기 때문에 원본 객체와 복사된 객체는 서로 같은 메모리를 공유
하고 있다.
만약 원본 객체나 복사된 객체 중 하나를 변경하면, 다른 하나도 영향을 받게 된다
.
const object = {0: 'a', 1: 'b'}const a = objecta[0] = 0object // {0: 0, 1: 'b'}object[0] = 'a'a // {0: 'a', 1: 'b'}
얕은 복사는 객체나 배열의 최상위 구조만 복사하므로, 내부의 객체나 배열은 복사하지 않는다.
따라서 내부 객체나 배열의 구조를 변경하지 않으면서 상위 레벨의 구조를 변경하려는 경우에는 얕은 복사를 사용한다.
const object = {0: 'a', 1: 'b', 2: {0: 'c', 1: 'd'}}const a = {...object}a[2][0] = 'e'object[2][0] // 'e'a[2][0] // 'e'
얕은복사를 하는 방법
const object = {0: 'a', 1: 'b'}const a = Object.assign({}, object)
const object = {0: 'a', 1: 'b'}const a = {...object}

얕은 복사 (Shallow Copy) | 깊은 복사 (Deep Copy) | |
---|---|---|
정의 | 원본 객체의 주소값을 복사해서 새 객체를 생성. 따라서 원본 객체와 복사된 객체는 같은 메모리를 공유. | 원본 객체의 값을 복사해서 완전히 새로운 객체를 생성. 원본 객체와 복사된 객체는 서로 다른 메모리를 가지며, 이 둘은 서로에게 영향을 주지 않음. |
사용 경우 | 객체의 상위 레벨만 복사하고 싶을 때 사용. 주로 메모리 사용량을 최소화하고자 할 때 유용. | 객체의 모든 레벨(상위 레벨과 하위 레벨)을 복사하고 싶을 때 사용. 주로 원본 데이터를 보존하면서 복사본에서 변경을 가하고 싶을 때 유용. |
참고
[C, C++] Call by value, Call by reference 쉽게 이해하기
Call by value, Call by reference 차이 (자바에서의 Call by value, Call by reference)
C와 JavaScript 에서 Call by value
, Call by reference
, Shallow Copy
, Deep Copy
의 주요 차이점
C | JavaScript | |
---|---|---|
Call by value | 값 자체를 복사해서 함수에 전달. 원본 변수에는 영향을 주지 않음. | 원시 타입(숫자, 문자열, 불리언 등)은 값을 복사해서 함수에 전달. 원본 변수에는 영향을 주지 않음. |
Call by reference | 변수의 주소를 복사해 서 함수에 전달. 원본 변수를 직접 변경할 수 있음. | 객체는 참조를 통해 함수에 전달. 원본 객체를 직접 변경할 수 있음. |
Shallow Copy | 지원하지 않음. | 객체의 주소값을 복사해서 새로운 객체를 생성. 원본 객체와 복사된 객체는 같은 메모리를 공유. |
Deep Copy | 직접 구현해야 함. 원본 변수와 복사본이 완전히 독립적. | JSON.parse(JSON.stringify(obj)) 등의 방법으로 구현. 원본 객체와 복사된 객체는 독립적. |
나중에 더 찾아볼 내용 (from GPT)
"Call by value"에 대한 부분에서,
원시 데이터 타입 (예: 숫자, 문자열, 불리언)
에 대해 더 이야기해 볼 수 있습니다.
JavaScript와 같은 언어에서는 원시 데이터 타입이 항상 call by value 방식으로 전달됩니다."Call by reference"에 대한 부분에서,
참조 데이터 타입 (예: 객체, 배열, 함수)
에 대해 더 이야기해 볼 수 있습니다.
JavaScript와 같은 언어에서는 참조 데이터 타입이 기본적으로 call by reference 방식으로 전달됩니다."Shallow copy"와 "Deep copy"에 대한 부분에서,
중첩된 객체에 대한 처리
를 언급할 수 있습니다.
Shallow copy는 객체의 최상위 레벨만 복사하고, 중첩된 객체에 대해서는 참조를 유지합니다.
반면에 deep copy는 중첩된 객체까지 복사하여 완전히 새로운 객체를 만듭니다.
이 차이점으로 인해 두 복사 방식이 다른 결과를 가져올 수 있습니다.