CallByReference VS CallByValue

Minsang Yu·2023년 4월 5일
0

1. Call By Value(값에 의한 호출)

  • 인자로 받은 값을 복사해서 처리를 한다.
  • 장점 : 값을 복사하기 떄문에 기존 원래의 값이 보존되어 안전하다.
  • 단점 : 메모리를 추가로 할당해야 하기 떄문에 메모리 사용량이 늘어난다.
#include <stdio.h>

void swap(int num1, int num2)
{
	int temp = num1;
    num1 = num2;
    num2 = temp;
}

void main()
{
    int a = 20, b = 60;
    swap(a, b);
    printf("a: %d, b: %d", a, b);
}

이러면 결과로 a는 20, b는 60이 나온다.

swap()을 호출하면 a와 b의 값만 받아와 내부적으로만 num1 과 num2를 변경하고 힙 메모리에 있는 변수에는 아무것도 넘기지 않는다.

변수를 주소로 가져오거나 포인터로 가져와야 힙 메모리에 있는 변수가 변경된다.

이 경우 교체는 되지 않고 swpa() 내부에서만 처리가 된다.

2. Call By reference(참조에 의한 호출)

  • 인자로 받은 값의 주소를 참조하여 직접 값에 영향을 준다.
  • 인자로 받은 값의 주소로 직접 참조
  • 장점 : 복사하지 않고 직접 처리하기떄문에 빠르다.
  • 단점 : 직접 참조를 하기 떄문에 원래 값이 영향을 받는다.
#include <stdio.h>
 
void swap(int &num1, int &num2)
{
    int temp = num1;
    num1 = num2;
    num2 = temp;
}

void main()
{
    int a = 20, b = 60;
    swap(a, b);
    printf("a: %d, b: %d", a, b);
}

위의 함수는 Main의 a와 b의 주소를 가져와서 처리했다.

직접 주소를 참조하기 떄문에 메인 함수의 메모리에 있는 a,b가 변한것을 볼수있다.

이런 방법으로 주소나 포인터를 사용하면 직접 변수에 접근하기 떄문에 장점도 있지만 리스크도 있다.

3. 깊은 복사(Deep Copy) VS 얕은 복사 (shallow Copy)

기본적으로 복사 생성자는 얕은 복사로 구현되어야 하지만 깊은 복사가 필요하다면 별도의 복사 생성자를 만들어야 한다.

3. 자바에서의 CallByReference, CallByValue

자바에서는 포인터가 따로 없으며 기본적인 매개변수는 Call By Value지만 예외적으로 배열과 클래스는 참조변수로 Call by Referenc로 작동한다.

따라서 swap과 같은 메모리 주소의 변수의값을 바꾸는 메서드를 구현할때는 배열이나 클래스를 이용해 구현해야한다.

1.배열을 이용

Integer[] arr = {1,2,3,4,5};

swap(arr, 0, 4);

private static <T> void swap(T[] a, int f, int r) {
	T temp;
    temp = a[f];
    a[f] = a[r];
    a[r] = temp;
}

배열과 인덱스를 넘겨주는 방식이다.

arr은 배열 그 자체가 아닌 배열의 첫번쨰 원소가 저장된 메모리 공간의 주소가 담겨 있다.

따라서 swap매서드의 a[f]=a[R] 같은 연산을 수행하면 실제 메모리의 배열의 값이 변경된다.

2. 객체 이용

public class Main{
	int value;
	
	public static void main(String[] args){
		
		Main m1 = new Main(10);
		Main m2 = new Main(20);
		
		System.out.println(m1.value + " " + m2.value);
		
		swap2(m1,m2);
		
		System.out.println(m1.value + " " + m2.value);
		
	}
	
	public Main(int a) {
		this.value = a;
	}
	
	private static void swap2(Main a, Main b) {
		int temp;
	    temp = a.value;
	    a.value = b.value;
	    b.value = temp;
		
	}
}

객체는 메모리 주소를 가리키기 떄문에 객체를 사용하면 메모리에 직접 접근할 수 있다.

profile
Jr. DataEngineer

0개의 댓글