Skip to content

Latest commit

 

History

History
142 lines (82 loc) · 5.38 KB

Call by value vs Call by reference.md

File metadata and controls

142 lines (82 loc) · 5.38 KB

Call by value vs Call by reference

Call by value

  • 값을 호출하는 것
  • 전달받은 값을 복사하여 처리
  • 전달받은 값을 변경하여도 원본은 변경되지 않음

함수가 호출될 때 메모리 공간 안에서는 임시공간이 생긴다. 함수가 종료되면 해당 공간은 사라진다. (스택) 함수 호출시 전달되는 변수의 값을 복사하여 함수의 인자로 전달한다. 복사된 인자는 함수안에서 지역적으로 사용하는 변수이다.

Call by reference

  • 참조에 의한 호출
  • 전달받은 값을 직접 참조
  • 주소값을 넘김

함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달한다.

함수안에서 인자의 값이 변경되면 함수 호출시 있던 변수들도 값이 바뀐다.

절차지향언어인 C언어는 Call by Value(값에 의한 호출)을 사용한다. 그리고 C++언어에서는 Call By Reference 사용이 가능하다.

int a = 10; // 일반 변수
int* p = &a; // 포인터 변수
int &b = a; // 참조 변수(reference value), c++에서만 가능

정리 , 장단점

C, C++에서는 함수는 두 가지 방법으로 호출

함수에 전달되는 매개변수를 실제 매개변수라고 부르고 함수가 전달받은 매개변수를 형식 매개변수라고 부름

  1. Call by value
    1. 실제 매개변수의 값은 형식 매개변수에 복사되고 두 유형의 매개변수는 서로 다른 메모리에 저장된다.
    2. 함수 내에서의 변경은 실제로 전달된 실제 매개변수에 반영되지 않는다.
    3. 장점
      1. 매개변수로 전달된 값이 보존되고 안전하다
    4. 단점
      1. 복사를 하는 과정에서 메모리 사용량이 늘어난다.
  2. Call by Reference
    1. 실제 매개변수와 형식 매개변수 모두 동일한 메모리를 참조하므로 함수 내에서 변경한 내용이 실제로 전달된 실제 매개변수에 반영
    2. 장점
      1. 복사하지 않고 직접 참조를 하기때문에 실행속도가 빠르다

      2. [개인적의견추가] 이부분에 대해서는 좀 애매한게 ..
        큰 객체, 클래스, 배열등의 경우에는 직접참조가 빠르지만 자바에서 원시타입을 참조형으로 만들지 않는 이유는 그것들은 스택에서 바로 사용하는게 빠르기때문인 것 같다. 
        
    3. 단점
      1. 장점일수도) 원래의 값이 영향을 받는다.
    4. C언어에서는 *,&로 전달 C++에서는 &로 전달

Java에서는 항상 Call by Value. 자바는 객체를 메서드로 넘길 때 참조하는 지역변수의 실제 주소를 넘기는 것이 아니라 그 지역변수가 가리키고 있는 힙 영역의 객체를 가리키는 새로운 지역변수를 생성하여 그것을 통하여 같은 객체를 가리키도록 한다.

자바가 Call by Value인 이유

Java에서는 참조 타입을 사용하면 각 타입의 변수들은 주소값을 가지게된다. 주소 '값'을 가지는 것이므로 Call By Value로 동작한다.

자바의 원시타입

  • null 불가능
  • 제네릭 불가능

사용하는 이유, 장점

  • 접근속도 (스택에 메모리에 그대로 존재함)
    • 반면 참조타입은 하나의 인스턴스로 스택 메모리에는 참조값만 있고 실제값은 힙 메모리에 존재
    • 값이 필요할 때 마다 언박싱 과정을 거쳐야해서 접근속도가 느리다.
  • 차지하는 메모리의 양이 참조타입이 훨씬 많다.

기본형과 참조형

자료형은 크게 기본형과 참조형 두가지로 나눌 수 있는데, 기본형 변수는 실제 값(data)를 저장하는 반면, 참조형 변수는 어떤값이 저장되어 있는 주소를 값으로 갖는다.

자바는 C언어와 달리 참조형 변수 간의 연산을 할 수 없으므로 실제 연산에 사용되는 것은 모두 기본형 변수이다.

메모리에는 1byte단위로 일련변호가 붙어있는데 이 번호를 메모리주소 또는 간단히 주소라고 한다. 객체의 주소는 객체가 저장된 메모리 주소를 뜻한다. 

기본형(primitive type)

  • boolean, char, byte, int, short, long, float, double
  • 계산을 위한 실제 값을 저장
  • int는 CPU가 가장 효율적으로 처리할 수 있는 타입이며 효율적인 실행보다 메모리를 절약하려면 byte, short를 사용하면 된다.
  • 정수형 중에서는 int, 실수형 중에서는 double이 기본자료형
    • boolean : 1byte
    • char : 2byte
    • byte : 1byte
    • int : 4byte
    • short : 2byte, long : 8byte
    • float : 부동소수점 방식
    • double : float보다 두배크기(8byte)

참조형(reference type)

  • 객체의 주소를 저장
  • 기본형을 제외한 나머지타입

참조형 변수(또는 참조 변수)를 선언할 때는 변수의 타입으로 클래스의 이름을 사용하므로 클래스의 이름이 참조변수의 타입이 된다. 그래서 새로운 클래스를 작성한다는 것은 새로운 참조형을 추가하는 셈이다.

참조형 선언

클래스이름 변수이름;

참조형 변수는 null또는 객체의 주소 (4byte 0x0 ~ 0xFFFFFFFF)를 값으로 갖는다. JVM이 64bit라면 참조형 변수의 크기는 8byte가 된다.