강의노트 12. 함수 호출방식(call-by-value, call-by-reference, call-by-assignment)
11 Apr 2017 |패스트캠퍼스 컴퓨터공학 입문 수업을 듣고 중요한 내용을 정리했습니다. 개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
함수의 호출방식
call-by-value (값에 의한 호출)
- 함수가 호출될 때, 메모리 공간 안에서는
함수를 위한 별도의 임시 공간
이 생성된다. (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.
- 참고 : Call by value(점프투자바)
- 참고 : 자바의 아규먼트 전달 방식
- 참고 : 생활코딩
- 참고 : Python은 Call by value인가 Call by reference인가.