레퍼런스로 함수에 인수 전달하기 

C++에서 함수에 인수를 전달하는 방법은 크게 세가지가 있습니다.

 

값을 전달하는 방식 - Pass by Value

 

② 포인터를 사용한 참조 전달 방식 - Pass by Reference using Pointer

 

③ 레퍼런스 전달 방식 - Pass by Reference

 

값을 전달하는 방식은 함수를 호출할 때 전달한 인수를 매개변수에 복사하여 사용하기 때문에 원본 데이터에 영향을 미치지 못합니다. 함수의 실행이 끝날 때 오직 하나의 값이 리턴되기 때문에 여러개의 반환값을 받을 수가 없죠. 예를 들어 두 변수의 값을 바꾸는 경우는 하나의 반환값으로 해결이 안됩니다.

 

이런 경우 포인터를 사용해서 참조를 전달하면 이 문제가 해결됩니다.

 

포인터 뿐 아니라 레퍼런스를 사용해도 됩니다.

 

swap 함수를 사용해서 알아보겠습니다.

 

1. Pass by Value (값을 전달)

함수를 호출하면 매개변수는 지역변수로 선언됩니다. 함수 호출이 종료할 때 소멸되죠. 즉 지역변수에서 매개변수를 조작해도 다시 바깥으로(main 으로) 나오면 그 내용은 사라집니다. 물론 처음부터 main 에서 전달한 인수에는 아무런 영향도 없습니다.

 

* 지역 mySwap의 변수들만 swap된 것을 볼 수 있고 main의 변수들은 영향이 없습니다.

2. 포인터를 사용한 참조를 전달 - Pass by Reference using Pointer

 

포인터를 사용하는 방식은 값 전달의 코드에 약간의 수정을 하면 됩니다.

 

우선 함수의 매개변수를 포인터로 선언합니다. 이렇게 되면 함수가 호출될 때 지역변수에는 정수형 포인터 두개가 만들어 집니다. 그리고 함수를 호출하면서 변수의 주소를 인수로 전달합니다. 여기서 & 는 주소연산자입니다. x와 y의 32비트(혹은 64비트) 주소값이 전달되겠죠.

 

여기서 다시 한번 구분해보면 인수는(argument) main함수에서 전달하는 값이고 매개변수(parameter)는 호출된 함수가 인수를 전달받아서 지역에 복사하여 생성하는 값입니다. 1번에서는 main에서 정수인 x, y 를 mySwap의 x, y에 그대로 복사했습니다. 그런데 여기서는 x, y의 주소를 받아서 포인터인 *ptrx, *ptry 에 저장하고 있습니다. 주는 쪽의 형식과 받는 쪽의 형식은 다르지만 호환이 되기 때문에 정상적으로 작동합니다.

 

실행하면 스왑 후 main 의 변수가 바뀌어있는 것을 볼 수 있습니다.

 

3. 레퍼런스 전달 방식 - Pass by Reference

세번째 레퍼런스 전달 방식입니다.

 

함수의 매개변수를 보면 레퍼런스 연산자 & 가 선언되어 있습니다. 레퍼런스 연산자는 주소연산자 &와 다르기 때문에 혼동에 주의합니다.

 

일단 매개변수를 레퍼런스로 받은 후에는 main 함수의 변수를 사용하는 것 처럼 값에 접근할 수 있습니다. 호출할 때의 형태를 보면 값 전달 방식(pass by value)와 동일합니다. 인수는 그냥 변수를 전달하고 있습니다. 이것을 함수에서 레퍼런스 변수로 받아가지고 갑니다.

 

아래와 같은 변수가 지역에 선언되는 것 이죠.

int &refx = x;

int &refy = y;

이들은 레퍼런스 변수의 특징을 그대로 가지고 있으니 원본의 값을 바꿀 수는 있어도 레퍼런스 변수 자체가 다른 정수형 변수를 가리킬 수가 없습니다. 안정성이 좋아지죠.

 

레퍼런스 전달로 main의 변수가 변경 된 것을 볼 수 있습니다.

정리

함수에 값을 전달하는 방식을 비교해보고 레퍼런스 전달 방식까지 알아봤습니다.

 

포인터로 작성된 것들은 레퍼런스 방식으로 재작성될 수 있는데 이렇게 하면 간접참조연산자 (* 역참조 연산자)를 사용하지 않아도 되니 코드가 읽기 쉽다는 장점이 있습니다.

 

포인터가 사용되는 곳에는 레퍼런스가 따라다닐 것 입니다. 레퍼런스에 대하여 정리를 잘 해 두면 도움이 됩니다.

 

* 레퍼런스 전달 방식 예제코드

#include <iostream>

void mySwap(int &x, int &y);

int main()
{
	int x = 9;
	int y = 77;

	Line;
	cout << " main | [스왑 전] x: " << x 
				 << " y: " << y << endl;
	
	mySwap(x, y);

	Line;
	cout << " main | [스왑 후] x: " << x
		<< " y: " << y << endl;
	return 0;
}

void mySwap(int &refx, int &refy)
{
	int temp;

	temp = refx;
	refx = refy;
	refy = temp;

	Line;
	cout << " mySwap | [스왑 후] *refx: " << refx
		<< " *refy: " << refy << endl;
}

공유하기

facebook twitter kakaoTalk kakaostory naver band