Developer

4.(C++) 레퍼런스 (Reference) 본문

Programming Language/C++

4.(C++) 레퍼런스 (Reference)

DPhater 2020. 8. 1. 22:38

레퍼런스(참조자)는 원하는 변수를 또 다른 이름으로 사용할 수 있게해준다. 쉽게 말하면 변수에 별명(Alias)을 정의해줄 수 있다.

자료형 &별명 = 별명을 부여할 대상

레퍼런스의 선언 방법은 위와 같다.주의할 점은 대상의 자료형과 별명의 자료형이 같아야 하며, 별명을 부여받는 대상은 실제 메모리를 점유하고 있는 좌변 값(l-value)이어야 한다. 또한 선언과 동시에 초기화해주어야 한다(초기화가 반드시 필요할 뿐 이후 대상을 변경할 수 있다).

#include<iostream>

using namespace std;

void swap(int x,int y){
	int temp=x;
	x=y;
	y=temp;
}

int main(void){
	int a=1,b=5;
	swap(a,b);
	cout<<"a : "<<a<<endl;
	cout<<"b : "<<b<<endl;
	return 0;
}

코드1 실행 결과

#include<iostream>

using namespace std;

void swap(int *x,int *y){
	int temp=*x;
	*x=*y;
	*y=temp;
}

int main(void){
	int a=1,b=5;
	swap(&a,&b);
	cout<<"a : "<<a<<endl;
	cout<<"b : "<<b<<endl;
	return 0;
}

코드2 실행 결과

 

코드1과 코드2는 C언어에서 call by vaule와 call by reference를 설명할 때 많이 사용하는 코드이다.

 

정상적으로 두 변수의 값이 swap되려면 포인터를 사용해 해당 변수의 주소를 보내서 다시 역참조(*)연산자를 사용해 함수를 작성해주어야 한다. 물론 함수를 호출할때 주소를 전달해 주어야하므로 주소 연산자(&)도 작성해주어야한다. 하지만 레퍼런스(참조자)를 사용하면 더 간단하게 사용이 가능하다.

#include<iostream>

using namespace std;

void swap(int &x,int &y){
	int temp=x;
	x=y;
	y=temp;
}

int main(void){
	int a=1,b=5;
	swap(a,b);
	cout<<"a : "<<a<<endl;
	cout<<"b : "<<b<<endl;
	return 0;
}

코드3 실행 결과

함수를 정의할 때 매개 변수를 레퍼런스를 사용해 선언하였다.

swap(a,b); 코드가 실행되면 swap함수의 정의부분으로 올라가 int &x=a, int &y=b; 가 실행되어 x와 y는 a와 b의 별명이 된다. 따라서 다른 연산자를 추가로 사용하지 않고 swap함수에서 main 함수에 있는 변수를 변경할 수 있는것이다.

이러한 레퍼런스에 사용에는 여러 장점이 있다. 함수를 호출할 때 주소 연산자를 사용하지 않아도 되고, 함수의 내용에서 역참조 연산자를 사용하지 않아도 된다. 만약 구조체를 전달한다면 ->연산자가 아닌 .연산자로 읽을 수 있다.

레퍼런스 주의점

1.레퍼런스에 대한 레퍼런스는 선언할 수 없다.(&&연산자 에러)

->레퍼런스로 다른 레퍼런스를 대상으로 한다면 결국 하나의 대상에 3개의 이름이 생기는 것이다.

2.레퍼런스에 대한 포인터는 선언할 수 없다.(&*연산자는 에러 ,포인터에 대한 레퍼런스는 가능)

3.레퍼런스의 배열은 선언할 수 없다.(배열의 레퍼런스는 가능)

레퍼런스와 포인터

레퍼런스의 사용법을 보면 포인터와 유사한 것을 알 수 있다. 사실 틀린말은 아니다. 실제 컴파일러는 레퍼런스를 포인터로 바꾸어 컴파일한다.

swap 함수를 예로 살펴보자.

void swap(int &x,int &y){
	int temp=x;
	x=y;
	y=temp;
}

위의 코드를 컴파일러는 아래의 코드로 바꾸어 컴파일한다.

void swap(int *x,int *y){
	int temp=*x;
	*x=*y;
	*x=temp;
}

물론 함수를 호출하는 코드도 swap(&a,&b)로 바뀐다.

레퍼런스와 상수

조금만 생각해보면 상수에 대한 레퍼런스는 필요 없다는 것을 알 수 있다. 상수는 좌변 값(l-value)가 아니므로 레퍼런스를 만들 수 없다. 하지만 레퍼런스를 선언할 때 const를 작성해주면 상수 레퍼런스를 만들 수 있다.

int &a=123; //에러 const int &a=123 //정상작동 const int a=123 //위의 상수 레퍼런스와 같음

위의 코드들을 보면 결국 상수 레퍼런스를 만들던 그냥 상수 변수를 만들던 똑같은 의미이므로 실용성이 없다.

'Programming Language > C++' 카테고리의 다른 글

6.(C++) 구조체  (0) 2020.08.01
5.(C++) 함수  (0) 2020.08.01
3.(C++) 제어문  (0) 2020.08.01
2.(C++) 입출력 및 자료형  (0) 2020.08.01
1.(C++) Hello World!  (0) 2020.08.01
Comments