
함수의 인수를 전달할 때 사용되는 방식은 크게 두가지로 분류할 수 있다.
Call By Value와 Call By Reference가 존재한다.
함수를 호출할 때 인자로 전달되는 값을 복사한 별개의 변수를 함수의 매개 변수로 전달하는 방식이다.
전달 받은 매개 변수에 대한 데이터 조작을 가해도 함수가 종료되었을 때 원본 데이터에 영향을 주지 않는다.
유명한 예시 중 하나인 Swap() 을 통해 확인해보자면
#include <iostream>
using namespace std;
void Swap(int x, int y)
{
int tmp = x;
x = y;
y = tmp;
}
int main()
{
int a = 10;
int b = 20;
Swap(a, b);
cout << "a : " << a << endl;
cout << "b : " << b << endl;
}
매개 변수로 전달되는 10과 20은 복사되어 전달되기 때문에 a , b , x , y 네 변수 모두 주소 값이 다르다.
Swap() 이 종료되기 직전 호출 스택은 다음과 같으며
복사된 x 와 y 의 값이 바뀐 것이기 때문에 a 와 b 는 값이 변하지 않는다.
함수를 호출할 때 인자로 전달되는 변수의 참조 값을 전달하는 방식이다.
전달 받은 변수의 값을 변경하면, 함수가 종료되더라도 변경된 값이 유지된다.
이는 Call By Value처럼 복사된 새로운 변수를 전달하는 것이 아니라 이미 선언된 기존의 변수를 참조의 형태로 전달하였기 때문이다.
마찬가지로 위의 Swap() 을 예시로 하면
#include <iostream>
using namespace std;
//매개 변수 앞에 주소 연산자가 포함
void Swap(int& x, int& y)
{
int tmp = x;
x = y;
y = tmp;
}
int main()
{
int a = 10;
int b = 20;
Swap(a, b);
cout << "a : " << a << endl;
cout << "b : " << b << endl;
}
Call By Value와는 다르게 정상적으로 swap이 진행된 것을 확인할 수 있다.
Call By Value와 똑같은 타이밍의 호출 스택을 확인해보면
각각 a 와 x , b 와 y 가 동일한 메모리 주소를 가리키고 있는 것을 알 수 있다.
C / C++ 에는 조금 특이한 방식의 전달 방식이 존재한다.
결과는 Call By Reference와 동일하게 나오지만 구조가 다른 Call By Address가 있다.
Call By Address는 어떻게 보면 Call By Value에 포함되어 있다고 볼 수도 있다.
Call By Address는 Call By Value와 마찬가지로 값을 복사하여 전달하지만 복사하는 대상이 값 그자체가 아니라 주소값을 복사하여 전달하는 방식이다.
#include <iostream>
using namespace std;
void Swap(int* x, int* y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
int main()
{
int a = 10;
int b = 20;
Swap(&a, &b);
cout << "a : " << a << endl;
cout << "b : " << b << endl;
}
코드 실행 결과는 동일하지만 호출 스택을 살펴보면
x 와 y 는 각각 a 와 b 의 주소값을 복사하여 저장하고 있는 것을 알 수 있다.
이는 변수의 메모리 할당에서도 확인할 수 있는데,
#include <iostream>
using namespace std;
void Reference(bool& value)
{
cout << "Call By Reference : " << sizeof(value) << endl;
}
void Address(bool* value)
{
cout << "Call By Address : " << sizeof(value) << endl;
}
int main()
{
bool b = true;
cout << "Main : " << sizeof(b) << endl;
Reference(b);
Address(&b);
}
1바이트 크기인 bool 변수를 선언하고 main() 과 Call By Reference 방식을 통해 매개 변수를 전달한 Reference() 에서 sizeof() 를 통해 바이트 크기를 확인하면 1바이트이다.
그러나 Call By Address 방식을 통해 매개변수를 전달한 Address() 에서 sizeof() 를 출력하면 8바이트가 출력된다.
Call by value vs Call by reference
[C 언어] Call by value, Call by reference 차이점 설명
[개발공통] Call by value와 Call by reference (Java, Python, C/C++)
[C, C++] Call by value, Call by reference 쉽게 이해하기
Call by Value 와 Call by Reference
[C++] call by value, call by address, call by reference 차이
Call by value Call by reference Call by address 정리c++