참조자

sz L·2023년 3월 22일
0

C++

목록 보기
9/40
post-thumbnail

참조자 : 별칭(별명)

자신이 참조하는 변수를 대신할 수 있는 또 하나의 이름

  • 할당된 하나의 메모리 공간에 둘 이상의 이름을 부여할 수 있음
  • 참조자도 변수로 봐도 무방
  • 참조자의 수에는 제한이 없으며, 참조자를 대상으로도 참조자를 선언할 수 있다.

헷갈리기 쉬운 포인터 주소연산자와 참조자

int *ptr = #
- 변수 num의 주소 값을 반환해서 포인터 ptr에 저장
int &num2 = num1;
- 변수 num1에 대한 참조자 num2를 선언

#include <iostream>
using namespace std;

int main()
{
	int num1 = 1020;
	int& num2 = num1;

	num2 = 3047;
	cout << "VAL: " << num1 << endl;
	cout << "REF: " << num2 << endl;
	cout << "VAL: " << &num1 << endl;
	cout << "REF: " << &num2 << endl;

	return 0;
}


  • 배열의 요소는 변수로 간주되어 참조자의 선언이 가능(배열은 불가능)
  • 포인터 변수도 변수이기 때문에 참조자 선언이 가능하다
#include <iostream>
using namespace std;

int main()
{
	int arr[3] = { 1,3,5 };
	int& ref1 = arr[0];
	int& ref2 = arr[1];
	int& ref3 = arr[2];

	cout << ref1 << endl;
	cout << ref2 << endl;
	cout << ref3 << endl;

	return 0;
}


포인터 변수의 참조자 선언

#include <iostream>
using namespace std;

int main()
{
	int num = 12;
	int* ptr = &num;
	int** dptr = &ptr;

	int& ref = num;
	int* (&pref) = ptr;
	int** (&dpref) = dptr;

	cout << ref << endl;
	cout << *pref << endl;
	cout << **dpref << endl;

	return 0;
}

int* (&pref) = ptr; pref는 포인터 변수 ptr의 참조자
int** (&dpref) = dptr; dpref는 포인터 변수 dptr의 참조자


매개변수 선언 위치에 참조자 올 수 있음

매개변수 선언 위치에 참조자가 온다면 할당된 메모리 공간에 데이터를 직접 접근하여 쓰겠다는 의미

#include <iostream>
using namespace std;

void swap(int& ref1, int& ref2)
{
	int temp = ref1;
	ref1 = ref2;
	ref2 = temp;
}

int main()
{
	int val1 = 10;
	int val2 = 20;

	swap(val1, val2);
	cout << "val1 : " << val1 << endl;
	cout << "val2 : " << val2 << endl;

	return 0;
}


반환형이 참조형인 경우

#include <iostream>
using namespace std;

int& RefRetFuncOne(int& ref)
{
	ref++;
	return ref;
}

int main()
{
	int num1 = 1;
	int& num2 = RefRetFuncOne(num1);

	num1++;
	num2++;
	cout << "num1: " << num1 << endl;
	cout << "num2: " << num2 << endl;

	return 0;
}

일반변수로 반환받아도 됨

#include <iostream>
using namespace std;

int& RefRetFuncOne(int& ref)
{
	ref++;
	return ref;
}

int main()
{
	int num1 = 1;
	int num2 = RefRetFuncOne(num1);

	num1++;
	num2+=10;
	cout << "num1: " << num1 << endl;
	cout << "num2: " << num2 << endl;

	return 0;
}

반환형이 일반형 매개변수가 참조형

#include <iostream>
using namespace std;

int RefRetFuncOne(int& ref)
{
	ref++;
	return ref;
}

int main()
{
	int num1 = 1;
	int num2 = RefRetFuncOne(num1);

	num1 += 1;
	num2 += 100;
	cout << "num1: " << num1 << endl;
	cout << "num2: " << num2 << endl;

	return 0;
}


잘못된 참조의 반환

int& RefRetFuncOne(int& ref) 일때
int& num2 = RefRetFuncOne(num1); (o)
int num2 = RefRetFuncOne(num1);  (o)
int RefRetFuncOne(int& ref) 일때
int& num2 = RefRetFuncOne(num1); (x)
int num2 = RefRetFuncOne(num1);  (o)
  • 지역변수를 참조형으로 반환하는 경우
int& RefRetFunc(int n)
{
	int num = 20;
    num += n;
    return num;
}

int main()
{
	int &ref = RefRetFunc(10);
}

지역변수인 num은 ref라는 이름이 붙게되지만 RefRetFunc함수의 호출이 끝나면 num은 소멸되고 ref는 존재하지 않는 메모리를 참조하게 되는면서 오류가 발생하게 된다.
num(지역변수)는 함수의 호출이 끝나게되면 지역변수도 소멸되기 때문에 지역변수는 참조형으로 반환하면 안된다.


const 참조자의 특징

참조자는 변수만 참조할 수 있다고 알고있지만 const를 같이 사용하게 된다면 상수도 참조할 수 있다.

const int &ref = 50;

const는 변수를 상수화 하게하는 연산자이기 때문에 const참조자는 변수도 참조가 가능하다.

  • 사용하는 이유
int Adder(const int &num1, const int &num1)
{
	return num1 + num2;
}

void main()
{
	cout << Adder(3, 4) << endl;
{

인자의 전달을 목적으로 변수를 선언한다는 것은 매우 번거롭지만, 임시변수의 생성을 통한 const 참조자의 상수참조를 허용함으로써, 간단히 호출이 가능해진다.

profile
가랑비는 맞는다 하지만 폭풍은 내 것이야

0개의 댓글