Call By Value
Call By Value란 값에 의한 호출로,
함수 호출 시 함수를 위한 별도의 메모리 공간을 생성하고(종료시 사라짐),
argument의 값을 복사하여 함수의 parameter 1로 전달한다. 2
복사된 인자는 지역변수의 특성을 가진다.
지역변수의 특징을 가지기 때문에, 내부에서 인자값을 변경하더라도 원본 인자값은 변경되지 않는다.
void func(int n){
n = 20;
}
void main(){
int n = 10;
func(n);
printf("%d", n); // 10이 출력됨!
}
Call By Address
call by value처럼 값을 복사해서 전달하는데, 주소값을 복사하는 것을 뜻한다.
아래에서 자바에서의 참조형타입을 넘길때의 형태.
결국 call by value라고 생각한다..
Call By Reference
Call By Reference란 참조에 의한 호출로,함수 호출 시 별도의 메모리 공간을 생성하고(함수 종료 시 사라짐)
argument의 레퍼런스(주소)를 전달한다.
따라서 함수 내부에서 인자의 값이 변경되면, 원본 인자값도 같이 변경된다.
void func(int *n){
*n = 20;
}
void main(){
int n = 10;
func(&n);
printf("%d", n); // 20이 출력됨!
}
Java는 Call By Value으로만 되어 있음
Java는 항상 Call By Value로만 값을 넘긴다.
기본형타입은 값을 그대로 가져가서 복사해서 쓸테니 넘어가고,
참조형타입은 해당 객체의 주소값을 복사해서 넘긴다고 생각하면 된다.
그로인해 객체의 프로퍼티에 접근은 가능하나, 객체자체를 변경할 순 없다.
public class Test {
public static class Person{
String name;
public Person(String name){
this.name = name;
}
public void setName(String name){
this.name = name;
}
public String toString(){
return name;
}
}
public static void main(String[] args) {
Person p = new Person("a");
System.out.println(p); // 원본변수 p 출력
createPerson(p); // p의 주소값을 복사하여 createPerson의 매개변수로 전달.
// 내부에서 매개변수에 다른 객체의 주소값을 저장하였지만,
// 내부에서 쓰는 p와 원본변수의 p는 다른 것이 됨.
// 처음엔 주소값이 동일하므로 같은 객체의 프로퍼티에 접근은 가능!
System.out.println(p);
changeName(p);
System.out.println(p);
} // main의 끝
public static void createPerson(Person p){
p = new Person("c");
System.out.println(p);
}
public static void changeName(Person p){
p.setName("b");
}
}
// 결과
a // 원본
c // 함수 실행 과정에서 출력
a // 함수 실행 후 main에서 출력
b // 함수로 프로퍼티 변경 후 출력
전달받은 매개변수는 원본변수의 주소값을 복사해서 가지고 있다.
그렇기때문에 같은 주소로서, 프로퍼티에 접근은 가능하다.
하지만 매개변수에 다른 객체의 주소를 넣는다고 쳐도, 원본변수의 주소값을 복사해서 가져온 것이기 때문에 매개변수에만 변경된다. 함수내에서 프린트 찍어보면 변경한 값으로 찍힌다.
call by reference 메모리 관점
하다보니 궁금한점이 생겼다.
call by value는 매개변수를 별도의 주소에 저장하고, 거기에 원본 값을 복사해서 넣어서 사용하는 형태라는 것은 이해했는데,
call by reference도 매개변수를 가질테고 해당 매개변수가 별도의 주소에 저장되면 어떻게 매개변수에 다른 객체를 대입하면 원본인자도 변경되는 것일까?
친구와 스택오버플로우의 도움을 받아 확인한 결과,
다르게 구현될 수 있지만 대표적인 예로 컴파일 과정에서 둘을 동일 시 취급해버리는 방법이 있었다.(그림2번 방법)
https://stackoverflow.com/questions/48626602/how-call-by-reference-work-in-c/48626745#48626745
일단 결론은 같은 call by reference이더라도
어떤 언어인지, 컴파일러는 뭔지, 최적화 옵션이 뭔지 이런거에 따라 모두 다르게 구현될 수 있다고 한다..
더 깊은 공부는 나중에... c++과 어셈블리 코드와 최적화까지 공부해야 알 수 있을 듯 싶다;
'CS > Basic' 카테고리의 다른 글
[Python] 객체복사,shallow copy,deep copy (0) | 2022.01.05 |
---|
댓글