brunch

You can make anything
by writing

C.S.Lewis

by 이남주 NJ Namju Lee Dec 11. 2020

Q 함수 호출,
참조/Reference, 값/Value

Computational Design


함수를 호출할 때, 전달인자(argument)를 같이 보내줘야 하는 경우가 있죠. - link


이 경우  두 가지를 생각해 볼 수 있어요. Call by value (값에 의한 호출) Call by reference (참조에 의한 호출)이 그것이죠.


이 개념을 왜 이해해야 할까요?


1) 알고리듬을 작성할 수 없기 때문에

인풋과 아웃풋의 데이터 흐름을 디자인할 때, 함수가 어떻게 호출이 되고, 값이 어떻게 업데이트가 되는지 모르면 프로그래밍 자체를 할 수 없죠!


2) 메모리와 속도의 최적화 문제

처음 시작하는 디자이너분들은, 지금 단계에서 고민할 필요는 없지만, 나중에, 실제 애플리케이션을 구현할 때, 컴퓨팅 속도와 메모리 공간의 최적화를 이해할 수 있게 되죠. 가령 쓸 때 없이, 함수 내부에서 복제가 일어나 시간과 메모리의 사용이 과다해질 수 있게 때문이죠. 반대로, 원본 값이 수정되어 결괏값이 잘못 나오는 경우도 생기죠.


일반적으로 

기본 타입(primitive type)은 벨류로, 그리고 오브젝트, 배열, 열거는 참조 타입(reference type)으로서 참조가 된다고 생각하자.


포인터를 사용하는 c 혹은 c++의 경우에는 명시적으로 참조 혹은 값으로 보낼 수 있죠.  하지만 여러분의 대부분은, 가비지 콜렉터가 작동하는 모던 언어를 주로 사용하여 코딩을 시작하는 디자이너 분들에게는, 굳이 지금 이해할 필요는 없어요.


일반적으로, 

기본 타입(primitive type)

숫자 int / float/ double

문자 char / string

논리 bool


의 경우 함수에서 값을 복사하여 내부적인 스콥에서 사용하게 되죠. 결국 어떠한 계산이 일어나더라도, 원본 값에는 영향을 미치지 않는 것이 포인트입니다! 즉 복제된 값에 의한 호출을 한 것이죠.


  public int Increase(int data){

      data++;

      return data;

  }


  int myNum = 2;

  Increase(myNum);

  Console.WriteLine("By value : " + myNum.ToString()); //  By value : 2


  int yourNum = 2;

  yourNum = Increase(yourNum);

  Console.WriteLine("By value : " + yourNum.ToString()); // By value : 3



하지만, 

참조 타입(reference type)

클래스 class

오브젝트 object

배열 array, list

열거 enum

인터페이스 interface


이번엔 오브젝트의 경우에는, 함수에서 값을 수정하면, 원본 값이 수정되는 것을 알 수 있죠? 참조가 발생했기 때문이죠. 즉 메모리의 주소 자체가 넘어가 버린 것이죠. 따라서 함수 안에서 그 주어진 데이터를 업데이트하면, 원본 데이터에 영향을 미치게 되는 것이죠!


  public List<int> Increase(List<int> data){

      data[0]++;

      return data;

  }

  public List<int> IncreaseByValue(List<int> data){

      List<int> dataNew = new List<int>();

      dataNew.Add(data[0] + 1);

      return dataNew;

  }


  List < int> myNum = new List<int>(){2};

  Increase(myNum);

  Console.WriteLine("By ref : " + myNum[0].ToString()); //  By ref : 3


  List < int> youNum = new List<int>(){2};

  IncreaseByValue(youNum);

  Console.WriteLine("By value : " + youNum[0].ToString()); // By value : 2



Class 예제

  public class Person {

      public int age = 2;

      public double height = 90;

  }

  public Person Increase(Person data){

      data.age++;

      return data;

  }

  public Person IncreaseByValue(Person data){

      Person p = new Person();

      p.age = data.age + 1;

      return data;

  }


 Person p0 = new Person();

 Increase(p0);

 Console.WriteLine("By ref : " + p0.age.ToString()); // By ref : 3


 Person p1 = new Person();

 IncreaseByValue(p1);

 Console.WriteLine("By value : " + p1.age.ToString()); // By ref : 2



* 그라스하퍼는 일반적으로 by value로 볼 수 있어요.(몇몇 클래스 베이스는 by reference 죠)

* c 혹은 c++의 환경에서는 더 복잡한 컨디션이 있을 수 있어요.

* 주어가 함수일 때는 Called by, 인수일 때는 Passed by라고 하네요.

* 기본적인 개념을 이해한 후, 더 깊이 있는 내용은, 

   최적화시키고자 하는 상황에 맞는, 더 자세한 문서를 참조해주세요. 


혹시 잘못된 내용 있으면 댓글로 지적 부탁드립니다.

감사합니다!


비디오 버젼


DATA & DESIGN 컴퓨테이셔널 디자인 바로가기

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari