[C++] 2. 참조자(레퍼런스)의 도입

Sireal·2022년 2월 16일
0

Google C++ 스타일 가이드에서 변수이름 규칙을 익히고 시작하자

  • 전역변수 = 소문자_소문자
  • 함수 = 동사형으로 낙타형태
  • 변수 =
  • 낙타형태와 언더바(_) 를 섞어서 사용하면 나중에 보기 힘들어진다.

문법구조

문법구조는 (if, else, while, for, switch, case 등) C랑 전반적으로 같다.
C에서 하던거 거의 전~부 다 된다고 보면 됨.


참조자(레퍼런스)

C에서는 포인터만 사용하여 목표값을 변경하는 등 했는데, C++은 레퍼런스 라는 친구를 사용한다.

  • 참조자(레퍼런스) : 해당 변수의 다른 이름(별명)
해당 자료형& 별명 = 해당 변수;
  • 컴파일러에게 해당변수의 별명이 있다는 걸 선언하는거라고 생각하는게 편함
#include <iostream>

int main(){
	int a = 3;

	int& another_a = a;

	another_a = 5;

	std::cout << "a : " << a << std::endl;
	std::cout << "another_a : " <<another_a << std::endl;

	return 0;
}

위의 코드는 레퍼런스 변수의 사용 예

  • a의 레퍼런스 변수 another_a를 선언했다.

레퍼런스는 한번 별명이 부여되면, 다른 값의 별명이 될수 없음

int a = 5;
int& another_a = a;

int b = 10;
&another_a = b; // 이렇게 사용 불가능.

함수인자로 레퍼런스 받기

#include <iostream>

int change_val(int &p){
	p = 10;

	return 0;
}

int main(){
	int a = 3;

	std::cout << "a : " << a << std::endl;
	change_val(a);
	std::cout << "a : " << a << std::endl;

	return 0;
}
  • 결과는 3, 5 가 나왔다.

int change_val(int &p) 함수에서, 이렇게 change_val(a) 그냥 변수를 넣었더니 값이 바껴서 나왔다.
사실 int &p = a; 처럼 사용됐다고 봐도 된다.

여러가지 레퍼런스들

#include <iostream>

int main(){
	int x;
	int& y = x;
	int& z = y;
	
	x=1;
	std::cout<< "x : "<< x << " y : " << y << " z : " << z << std::endl;
	y=2;
	std::cout<< "x : "<< x << " y : " << y << " z : " << z << std::endl;
	z=3;
	std::cout<< "x : "<< x << " y : " << y << " z : " << z << std::endl;


	return 0;
}

/* -- 결과 값 --
x : 1 y : 1 z : 1
x : 2 y : 2 z : 2
x : 3 y : 3 z : 3
*/

하나의 변수에 레퍼런스를 여러개 선언 후 변수들을 각각 넣었지만,
변수와 레퍼런스들이 같은 값이 나온다.

  • 레퍼런스는 그냥 해당변수(x)의 별명이라고 생각하면 쉽게 이해가 된다.

상수에 대한 참조자 (안됨)

#include <iostream>

int main() {
  int &ref = 4;

  std::cout << ref << std::endl;
}

리터럴 상수를 참조자로 가져가면, 오류가 뜬다.
상수를 참조자가 가져가서 쓸일 도 없을 뿐더러, 문법적으로 못쓰게 막아뒀다.

레퍼런스의 배열과 배열의 레퍼런스

레퍼런스의 레퍼런스, 레퍼런스의 배열, 레퍼런스의 포인터는 존재할 수 없다.

  • 하지만! 레퍼런스 배열을 선언하는 방법은 있다.
#include <iostream>

int main(){
	int arr[2] = {1,2};

	int (&ref)[2] = arr;

	return 0;
}

이런식으로는 사용가능.

레퍼런스를 리턴하는 함수

  • 레퍼런스 함수로 레퍼런스 인자를 받고 그 인자를 리턴하는 형식은 가능
int& function(int& a){
	a = 5;
	return a;
}
  • 레퍼런스 함수로 레퍼런스 함수에 있는 지역변수를 리턴하는 형식은 불가능
int& function(){
	int& a = 5;
	return a;
}

사라진 지역변수를 레퍼런스로 사용해도 의미가 없어서 문법으로 막아버림.

  • 이와 비슷한 맥락으로 아래와 같은 코드도 불가능
int function(){
	int a = 5;
	return a;
}

int main(){
	int& c = function();
    return 0;
}

사라진 지역변수에게 별명을 왜 붙여줘.. 그래서 문법으로 막아버림.

레퍼런스는 메모리에 없을 수도 있다.

그냥 별칭으로만 쓰이면 메모리에 안남아 있고, 지역변수처럼 쓰이면 메모리에 남아있게 된다.

profile
달리다 넘어져도 아픔마저 즐기려하는 사람

0개의 댓글