(언어별) Pass-by-value, Pass-by-reference 정리
기본 개념
Techniques for passing data (argument) to the function
함수에 데이터, 값을 넘겨주는 방식
Pass-by-value
num은 스택 메모리에 따로 copy된 값.
그 값 바꿔도, 함수 종료시에 사라짐
void add(int num){
num = num + 1;
}
int main(){
int var = 1;
add(var);
cout << var << "\n"; // 1
return 0;
}
Pass-by-reference
(Pointer를 활용해서) argument num에 새 값을 대입해도, num으로 넘겨준 var 값이 바뀌어짐.
num은 var의 다른 이름 (alias) 처럼 쓰이는 것 - 참고
void add(int& num){
num = num + 1;
}
int main(){
int var = 1;
add(var);
cout << var << "\n"; // 2
return 0;
}
언어별 정리
사용하는 언어가 많아지다보니, 헷갈리기도 하고 제대로 모르는 경우도 많은 것 같아서 정리
C
Only Pass-by-value
Primitives (int, char, boolean 등) - Pass-by-value
포인터 (배열) - 얘도 pass-by-value!! (참고)
* 포인터 넘겨주는 것도 pass-by-value;
passing pointers to 'emulate' pass-by-reference (사실 pass-by-reference 구현 자체를 포인터 개념으로 하긴 함. 둘이 매우 밀접하게 연관됨)
https://stackoverflow.com/questions/2229498/passing-by-reference-in-c
C++
C랑 동일
포인터 대신 reference 넘기기 가능 - 진짜 Pass-by-reference
* reference is internally implemented with pointers (https://godbolt.org/ 에서 실습 가능)
https://stackoverflow.com/questions/3954764/how-are-references-implemented-internally
예시 - https://www.cs.utah.edu/~germain/PPS/Topics/C_Language/c_functions.html
Java
(C처럼) Only Pass-by-value
Object 생성 시, 그 Object 데이터가 저장된 메모리를 가리키는 포인터 반환함. 그걸 reference라고 부름.
(The value associated with an object is actually a pointer, called a reference, to the object in memory)
Foo foo = new Foo(); // foo : Not the `Foo` object created, but pointer to the created `Foo` object
💡 함수 호출 시 Object 넘겨주는 경우, caller의 reference를 copy해서 callee에게 넘겨줌
reference 통해서 Object method 호출하거나 field값 변경 가능하나,
callee reference에 새 값 assignment해서 가리키는 Object를 바꿔도 기존 caller쪽 reference는 바뀌지 않음 (pointer를 copy 해서 넘겨줬으니까)
// bar is copied reference of foo; They point to same thing, but are different pointers
public void test(Foo bar){
bar.print(); // "Original"
bar = new Foo("New"); // ⚡️ reference 'bar' now points to a new Foo object created
bar.print(); // "New"
}
Foo foo = new Foo("Original");
test(foo);
foo.print(); // "Original" - reference 'foo' is intact
그림 설명
process함수 내부에서 foo = 0; 을 하면, foo가 가리키던 0x07000 메모리 위치에 이젠 0x07070이 아닌 0이 저장되겠지.
변수는 메모리 주소를 쉽게 부르기 위한 이름/별명! (https://goldenriver42.tistory.com/57?category=923014)
⭐️ 좋은 ref1) https://dzone.com/articles/pass-by-value-vs-reference-in-java
⭐️좋은 ref2) https://jonskeet.uk/java/passing.html
Python
Java랑 동일. Pass-by-value (Object reference)
Pass-by-object-reference, pass-by-assignment 같은 여러 이름이 있는 것 같은데,
결국 immutable은 우리가 흔히 아는 pass-by-value,
Mutable object의 경우 reference를 pass-by-value로 넘겨줌
https://goldenriver42.tistory.com/213?category=923013
Javascript
Java랑 동일. Pass-by-value (Object reference)
https://www.javascripttutorial.net/javascript-pass-by-value/
pass-by-reference is obsolete?
요즘 등장하는 high-level, high-abstract 언어들은 모두 Pass-by-value가 아닐까 싶은데.
C/C++의 경우 프로그래머가 메모리를 직접 건들이기 때문에 pass-by-value/pass-by-reference를 직접 지정해줄 수 있었는데, 이런 디테일을 다 추상화한 고차원 언어들은 못하니까.
Understanding the technique used to pass information between variables and into methods can be a difficult task for a Java developer, especially those accustomed to a much more verbose programming language, such as C or C++.
In these expressive languages, the developer is solely responsible for determining the technique used to pass information between different parts of the system. For example, C++ allows a developer to explicitly pass a piece of data either by value, by reference, or by pointer.
👏 Stackoverflow에 나랑 비슷한 생각 하는 사람이 있었다 - pass by reference 라는 개념은 obsolete
reference를 pass-by-value로 넘겨주고, 그 reference를 통해서 Object internals(내부 field 값)를 바꿀 수 있음.
reference에 새 값을 할당해도 이건 이미 copy된 포인터라서 호출 전 reference에는 영향 못줌.
Pass-by-value, Pass-by-reference 장/단점?
⚡️ (면접 Hot 질문) 각 언어별로 가지는 Pass-by 특징들이 어떤 장단점이 있는지, 상황을 예시를 들어 설명할 수 있어야 함
When to use pass-by-value/reference? 처럼
https://www.educative.io/edpresso/pass-by-value-vs-pass-by-reference
https://jonskeet.uk/java/passing.html#:~:text=Ways%20to%20avoid%20needing%20pass%2Dby%2Dreference
'<기타 공부> > [기타 프로그래밍 및 범용 CS]' 카테고리의 다른 글
언어 별 concept, philosophy (0) | 2022.04.21 |
---|---|
(언어별) Immutability 정리 (0) | 2022.01.29 |
[Linux] Git Bash에 man 추가 - bashrc, bash_profile 개념 (0) | 2022.01.13 |
[개발] ORM (Sequelize, TypeORM) (0) | 2022.01.10 |
[Linux] repository란? (0) | 2022.01.10 |