[C++] #5 참조자와 함수 - 참조자가 필요한 이유 Call-By-Value & Call-By-Reference

반응형
반응형

[목차]

# 참조자가 필요한 이유

*개인적인 C++ 공부 내용을 정리하는 용도로 작성된 글 이기에 잘못된 내용이 있을 수 있습니다.


# 참조자가 필요한 이유

앞선 #4 참조자(Reference) - 참조자는 변수의 별칭이다. 포스팅에서 참조자에 대해서 간략하게 알아 보았다. 하지만 여전히 왜 굳이 메모리 공간에 참조자라는 것을 사용해 별칭을 하나 더 지어 주어야 하는 지 찝찝한 기분이 사라지지 않을 것이다. 

사실 앞의 코드들은 단순히 예시일 뿐 이고, 참조자는 함수에서 큰 역할을 차지한다. 참조자를 사용하면 Call-By-Value 형태의 함수가 아닌, Call-By-Reference 형태의 함수를 선언할 수 있다.

예를 들어 변수 X 와 변수 B 의 값을 바꾸는 temp 함수를 아래와 같이 선언 했다고 가정해 보자.

// Call-By-Value
int ChangeValue(int x, int y)
{
	int tmp = x;
	x = y;
	y = tmp;
}

int main(){
	int x = 10;
	int y = 20;
	cout << "BEFORE " << "X : " << x << " Y : " << y << endl; 
	ChangeValue(x, y);
	cout << "AFTER " << "X : " << x << " Y : " << y;
	return 0;
}
[실행결과]
BEFORE X : 10 Y : 20
AFTER X : 10 Y : 20

 

결과를 확인해 보니, 예상한 바와 다르게 X와 Y의 값이 바뀌지 않았다. 그 이유는 ChangeValue 함수가 Call-By-Value 형태로 선언된 함수이기 때문이다. Call-By-Value 형태로 선언된 함수 내부에서는 함수 외부에 선언된 변수에 접근할 수 없다. 따라서, 함수 외부에 선언된 변수에 접근하고 싶다면 Call-By-Reference 형태로 함수를 선언해야 한다.

 

그렇다면 어떻게 Call-By-Reference 형태로 함수를 선언할 수 있을까? 방법은 2가지 있다. 악명 높은 포인터를 사용하는 방식과, 참조자를 사용하는 방식이다.

#include <iostream>
using namespace std;

// Call-By-Reference With Pointer
int ChangeValue1(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

// Call-By-Reference With Reference
int ChangeValue2(int &x, int &y)
{
	int tmp = x;
	x = y;
	y = tmp;
}

int main(){
	int x = 10;
	int y = 20;
	cout << "BEFORE " << "X : " << x << " Y : " << y << endl; 
	ChangeValue1(&x, &y);
	cout << "AFTER[Pointer] " << "X : " << x << " Y : " << y << endl;
	ChangeValue2(x, y);
	cout << "AFTER[Reference] " << "X : " << x << " Y : " << y;
	return 0;
}
[실행결과]
BEFORE X : 10 Y : 20
AFTER[Pointer] X : 20 Y : 10
AFTER[Reference] X : 10 Y : 20

포인터를 이용한 ChangeValue1 함수나, 참조자를 이용한 ChangeValue2 함수 둘다 동작은 동일하다. 프로그래머가 더 선호하는 방식을 택하여 Call-By-Reference 형태 함수를 선언하면 된다


반응형

댓글

Designed by JB FACTORY