언어 공부/C++

reference(참조)-2

세희홍 2022. 6. 21. 19:04

참조로 전달

#include <iostream>
using namespace std;
void test(int& rn) {
	rn = rn + 1;
	cout << &rn <<" " << rn << "\n"; // 00000035AE2FF8B4 11
}

int main() {
	int n = 10;
	test(n);
	cout << &n << " " << n << "\n"; // 00000035AE2FF8B4 11
}

 

레퍼런스 변수의 메모리 번지수와 n의 메모리 번지수가 같은 값이 나오게 된다. 

별도의 메모리 공간을 할당하지만 포인터와 비슷하게 동작한다.(포인터는 다른 번지수가 나온다.)

 

void pp(int& n) {
	n = n + 1;
}

int main() {
	int a = 1;
	pp(a);
	return 0;
}

 

함수의 매개변수에 const를 붙이면  원본 변수 수정 불가

void pp(const int& n) {
	n = n + 1; // 컴파일 에러. const reference 변수이므로 수정불가.read-only
}

int main() {
	int a = 1;
	pp(a);
	return 0;
}

const가 붙으면 호출되는 함수 안쪽에서 원본 쪽의 값을 변경하지 않을 때 사용한다.(읽는 용도)

const 붙이는 이유:

1. 성능 - 함수의 매개변수를 값으로 전달하면 그 값 전체가 복제가 된다. 레퍼런스로 전달하면 원본에 대한 포인터만 복사가 된다.

2. 원본 변수가 변경되지 않는다. 

-> 읽는 용도로 쓰거나 커다란 객체를 전달할 때 복사 비용을 줄이기 위해 사용한다. 

 

void test(const int& rn) { // 읽기 전용
	//rn = rn + 1; // 컴파일 오류. 값 변경 불가
	cout << &rn << ' ' << rn << endl; // 0000005E71F9F854 11
}

int main() {
	int n = 10;
	n = n + 1; 
	test(n);
	cout << &n << ' ' << n << endl; // 0000005E71F9F854 11
}

일반 변수에서 값을 바꿀 수 있지만, 레퍼런스 변수를 통한 값의 변경은 불가하다. (읽기 전용-원본의 값을 훼손시키지 않음)

 

void test(const int& rn) { // 읽기 전용
	//rn = rn + 1;
	cout << &rn << ' ' << rn << endl; // 0000005E71F9F854 10
}

int main() {
	const int n = 10;
	//n = n + 1; 
	test(n);
	cout << &n << ' ' << n << endl; // 0000005E71F9F854 10
}

const를 원본변수와 매개변수에 모두 붙이면 값 변경 불가.

 

void test(int& rn) { // 컴파일 에러
	rn = rn + 1;
	cout << &rn << ' ' << rn << endl; // 0000005E71F9F854 10
}

int main() {
	const int n = 10; 
	test(n);
	cout << &n << ' ' << n << endl; // 0000005E71F9F854 10
}

원본 변수에 const가 있는데 매개변수에는 없는 경우 컴파일 에러. 


void fun(int& rX) { ... }
fun(5); // 컴파일 오류

함수를 호출할 때는 변수를 매개변수로 넣어야 한다.

const int& s = 99;

레퍼런스 변수를 선언할 때는 값이 오면 안되고 다른 변수 이름이 와야한다. 하지만 const 키워드가 붙으면 레퍼런스 변수가 정수 리터럴도 받을 수 있다.

 


참조로 전달해서 둘 중에 큰 분수 찾기

#include "fraction.h"

Fraction& larger(Fraction&, Fraction&);  // 프로토타입

int main()
{
  // 첫 번째 쌍을 만들고 큰 값 탐색
  Fraction fract1(3, 13);
  Fraction fract2(5, 17);
  cout << "첫 번째 쌍에서 더 큰 분수: ";
  larger(fract1, fract2).print();
  // 두 번째 쌍을 만들고 큰 값 탐색  
  Fraction fract3(4, 9);
  Fraction fract4(1, 6);
  cout << "두 번째 쌍에서 더 큰 분수: ";
  larger(fract3, fract4).print();
  return 0;
}

Fraction& larger(Fraction& fract1, Fraction& fract2)
{
  if(fract1.getNumer() * fract2.getDenom() >
   fract2.getNumer() * fract1.getDenom())
  {
    return fract1;
  }
  return fract2;
}