본문 바로가기
  • 공부, 여행 리뷰해요~~!!
공부/C++

13. C++ Reference, 참조

by 하나리나 2022. 1. 27.
반응형

* 개인공부를 위한 기록입니다. 잘못된 점에 대한 지적 감사드립니다.

 

저는 MATLAB을 주로 사용하여 연구했던 사람입니다.

reference를 왜 쓸까? 라고 생각했을 때, 가장 먼저 떠오른 것은 메모리 측면에서 유리하다'라는 것입니다.(다른 이유가 더 있겠으나 지금 수준에서는 잘 모르겠습니다..)

 

예제를 보시며 하나씩 파악해 보도록 하겠습니다.

 

1. 먼저 정수형 변수 n을 하나 선언하겠습니다. 

int n = 0; // integer의 메모리는 4byte

n은 0으로 초기화 되었고, n은 integer이므로 4byte의 메모리에 저장됩니다.

 

 

2. n을 지칭하는 reference인 r을 하나 만들어 보겠습니다.

int& r = n;

reference r을 선언한 것은, 새로운 메모리 할당의 개념이 아닙니다. 

기존 n의 메모리에 새로운 이름 r을 부여한다' 정도로 생각하시면 될 것 같습니다.

 

 

3. n은 0으로 초기화 했었죠?

n을 지칭하는 r을 10으로 바꿔보겠습니다.

r = 10;

 

4. r은 n의 별칭(alias)를 만드는 것과 같은 의미이고,

n과 r의 주소는 같은 것임을 확인할 수 있습니다.

std::cout << &n << std::endl;
std::cout << &r << std::endl;

 

5. reference는 반드시 초기값이 있어야 합니다.

다음과 같이 선언만 한 경우 오류입니다.

// int& r2; // error!

 

6. 그럼 이제 처음에 말한 reference의 장점에 대해 말씀드려 보겠습니다.

예를 들어, 변수를 input으로 받는 Call_by_Value'라는 함수와 reference를 input으로 받는 Call_by_Ref'라는 함수를 만들겠습니다. 

(Pointer를 input으로 받을수도 있습니다!)

void Call_by_Value(int n) {
	n++;
}
void Call_by_Ref(int& n) {
	n++;
}

 

6.1.  Call by Value

변수를 입력으로 받을 경우, 함수 내부에서 input 값이 n으로 복사 됩니다.

따라서 메인함수에서 선언한 변수는 Call_by_Value'에 의한 동작에 영향을 받지 않습니다.

int n1 = 10;
Call_by_Value(n);
std::cout << n1 << std::endl;

 

6.2. Call by Reference

반면, Call_by_Reference'의 경우 int& n이 input 값의 메모리에 접근하므로 복사본을 만들지 않습니다.

결국, 구조체 등 변수 타입의 메모리가 큰 경우 call by reference를 사용하면 함수 내부에서 복사본을 만들지 않아도 됩니다.

따라서, 메모리 측면에서 유리하다고 할 수 있겠습니다.

int n2 = 10;
Call_by_Ref(n2);
std::cout << n2 << std::endl;

 

 

*) 아래 코드블럭은 예제를 위한 전체 코드입니다.

#include<iostream>

void Call_by_Value(int n) {
	n++;
}
void Call_by_Ref(int& n) {
	n++;
}

int main()
{
	int n = 0; // integer의 메모리는 4byte

	// 1. reference 타입
	// 새로운 메모리 할당의 개념이 아님.
	// 기존 n의 메모리에 새로운 이름 r을 부여 한다.
	int& r = n; 

	r = 10;
	
	//2. r과 n은 결국 같은 메모리이므로 결국 n = 0이 된다.
	std::cout << n << std::endl; 
	
	// 3. r은 n의 alias(별칭)을 만드는 것과 같은 의미이고,
	// n과 r의 주소는 같은 것임을 확인이 가능하다.
	std::cout << &n << std::endl;
	std::cout << &r << std::endl;

	// 4. reference는 반드시 초기값이 있어야 한다.
	// int& r2; // error!
	

	// 5. call by value.
	int n1 = 10;
	Call_by_Value(n);
	std::cout << n1 << std::endl;

	// 6. call by reference.
	// 구조체 등 변수 타입의 메모리가 큰 경우 call by reference를 사용하면
	// 함수 내부에서 복사본을 만들지 않아도 되므로 메모리 측면에서 유리하다!
	int n2 = 10;
	Call_by_Ref(n2);
	std::cout << n2 << std::endl;


}
반응형