함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다. (c++의 경우 stack frame) 함수가 종료되면 해당 공간은 사라진다.
스택 프레임(Stack Frame) : 함수 호출시 할당되는 메모리 블록(지역변수의 선언으로 인해 할당되는 메모리 블록)
call-by-value 값에 의한 호출방식은 함수 호출시 전달되는 변수의 값을 복사하여 함수의 인자로 전달한다.
복사된 인자는 함수 안에서 지역적으로 사용되는 local value의 특성을 가진다.
따라서 함수 안에서 인자의 값이 변경되어도, 외부의 변수의 값은 변경되지 않는다.
Java의 경우 함수에 전달되는 인자의 데이터 타입에 따라서 (원시자료형 / 참조자료형) 함수 호출 방식이 달라진다.
원시 자료형 (primitive type) : call-by-value 로 동작 (int, short, long, float, double, char, boolean )
참조 자료형 (reference type): call-by-reference 로 동작 (Array, Class Instance)
call-by-reference (참조에 의한 호출)
함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다. (예: stack frame) 함수가 종료되면 해당 공간은 사라진다.
call-by-reference 참조에 의한 호출방식은 함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달한다. (해당 변수를 가르킨다.)
`따라서 함수 안에서 인자의 값이 변경되면, 아규먼트로 전달된 객체의 값도 함께 변경된다.
call-by-value, call-by-reference 예시
#include <iostream>
using namespace std;
//두 수를 함수 내에서 바꿉니다.
void func_by_value(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
//두 수를 함수 내에서 바꿉니다.
void func_by_ref(int & a, int & b) //포인터로도 구현 가능
{
int temp = a;
a = b;
b = temp;
}
int main(void)
{
int a = 10;
int b = 20;
cout << "before function" << endl;
cout << "a : " << a << endl;
cout << " b : " << b << endl<<endl<<endl;
#if 0
func_by_value(a, b); // a, b 의 값은 그대로
#else
func_by_ref(a, b); // a, b 의 값이 서로 바뀌어 있다.
#endif
cout << "after function" << endl;
cout << "a : " << a << endl;
cout << " b : " << b << endl << endl << endl;
return 0;
}
call-by-assignment
파이썬의 경우 함수의 호출 방식으로 call-by-assignment을 사용한다.
파이썬에서는 모든 것이 객체이고, 객체에는 2가지 종류가 있다.
immutable object
int, float, str, tuple
immutable 객체가 함수의 arguments로 전달되면 처음에는 call by reference로 받지만, 값이 변경되면 call by value로 동작한다. 즉 함수 내에서 formal parameter 값이 바뀌어도, actual parameter에는 영향이 없다.
mutable object
list, dict, set
mutable 객체가 함수의 argument로 넘어가면 call by reference로 동작한다. 즉, object reference가 전달되어 actual parameter의 값에 영향을 미칠 수 있다.
def spam(eggs):
eggs.append(1) # call by reference로 동작 / caller scope까지 적용
eggs = [2, 3] # call by value로 동작, 새로운 객체를 가르킨다. / callee scope에는 적용되지만, caller scope까지는 적용되지 않는다.
print(eggs)
ham = [0]
spam(ham) # [2, 3]
print(ham) # [0, 1]
Parameter, Argument, 함수 호출방식 참고자료
Parameter : The names given in the function definition are called Parameters.
Argument : The values supplied in the function call are called Arguments.