우리는 프로그래밍을 하다 보면 반드시 함수/메서드를 사용하게 된다. 모든 기능을 메인함수 안에 넣을 수 없기에 코드의 가독성을 위해서나, 추상화나 재사용성을 위해서나. 유지보수를 위해서나 함수/메서드를 사용하는 것이 바람직하다. 어떤 언어를 사용하든 간에 매개변수를 이용한 함수를 사용한다면 아래 그림과 같이 사용할 것이다. 

 

 

먼저 함수가 호출되면 컴퓨터 일어나는 과정을 알 필요가 있다. 

 

함수가 호출되면 호출된 함수의 매개변수, 지역변수 반환 주소등 및 기타 상태 정보를 포함한 스택프레임이 메모리의 스택에 생성된다. 일종의 사용자정의 함수내에서 사용할 변수를 새로 선언하여 사용하는 것이다. 그리고 만들어진 사용자정의 함수의 매개변수로 인수가 전달이 된다. 이 과정이 복사의 과정이다. 그리고 제어권은 사용자정의 함수로 이동하여 함수가 실행된다. 그리고 반환값을 받고 해당 함수를 위해 생성된 스택프레임을 다시 반환하며 제어권을 다시 메인 함수로 이동하게 된다. 

 

위 과정에서 인수가 전달되는 방식들 중 대표적인 것이 값에 의한 호출과 참조에 의한 호출이다. 위 방법들은 언어들마다 형태만 다를 뿐 근본적인 원리는 동일하다. 두 호출 모두 인수를 복사(전달)를 한다는 점은 같지만 무엇을 복사하는지, 복사하는 변수에 무엇이 들어있는지 차이가 있다. 무엇을 복사하는지에 집중해서 자세히 알아보도록 하자.

 

값에 의한 호출 ( Call by value)

 

값에 의한 호출은 말 그대로 인수 자체의 값, 즉 메모리 안에 담겨 있는 값을 복사하는 방식이다.  그렇기에 사용자정의 함수에서는 값만 같을 뿐 전혀 다른 변수(스택프레임에서 생성된, 메모리 주소조차 다른)를 이용해 함수를 실행시키는 것이다. 그렇기에 메인함수에서 인자로 사용했던 변수들에 직접적인 영향을 주지 못한다는 특징이 있다. 

 

참조에 의한 호출 ( Call by reference)

 

참조에 의한 호출은 주소(번지)가 담겨있는 변수의 내용을 복사하는 방식이다.

 

참조형 변수 예시

 

위 그림과 같이 어떤 배열의 주소를 저장하는 참조형 변수가 있다고 한다면 함수 호출의 인자로 a와 b변수의 내용을 전달하는 것이 참조에 의한 호출이다. a와 b변수 안에는 배열의 위치(번지)를 담고 있다. 그렇기에 호출된 함수의 매개변수로 넘어온 변수는 실제 main에서 사용한 변수가 가리키는 배열과 일치하다. 그래서 참조에 의한 호출을 통해 무언가를 수정했다면 메인함수에서 사용했던 변수들에게 직접적인 영향을 줄 수 있다. 

 

참조형 변수는 언어마다 다른 표현방식을 가지고 있다. 파이썬에서는 리스트, 자바에서는 배열 객체, 참조형 변수,  C언어에서는 배열의 이름, 포인터 등 다양한 방식으로 표현되지만 그 원리는 같다. 인자로 전달받는 변수의 내용이 값(value)냐 주소/번지(reference)이냐의 차이일 뿐이다.