개발자 면접 공부/C-C++

C++ 포인터(Pointer) 레퍼런스(Reference) 차이

chogyujin 2022. 7. 11. 22:42
728x90

포인터와 레퍼런스에 차이

 


시작

포인터(Pointer)와 레퍼런스(Reference)는 보면 둘다 참조를 하는 변수임은 똑같다고 생각을 하였다.

하지만 이 둘도 엄연히 차이점이 존재하였다. 그 차이점을 알아보자.

 


1.NULL의 허용 여부

일단 NULL을 허용하냐 안하냐에서 차이점이 난다.

 

포인터는 NULL 즉 nullptr도 허용이 되지만 레퍼런스 만큼은 허용이 되지않습니다.

포인터는 즉 NULL을 가르키거나 초기화 하지 않을경우 Null pointer exception 또는 Segmentation Fault 에러를 난다.

 

따라서 포인터는 반드시 Null Check 를 해줘 코드를 처리를 해줘야 에러를 방지할수 있습니다.

 

Student S = new Student();

if(S!=nullptr)
{
	S->Print();
}
else
{
	cout<<"Error"<<endl;
}

 

언제나 포인터는 방어를 해야하기 때문입니다.

하지만 레퍼런스(&)는 NULL을 허용하지 않습니다.

 

int &b = NULL //에러 NULL은 참조 할수가 없음

 

이러한 경우는 다음과 같을수 있습니다.

 

#include<iostream>

using namespace std;

int main()
{
	int a = 5;
	int* p = &a;
	int& r = a;
}

 

포인터 = 주소를 저장하는 변수

레퍼런스 = 직접 그 변수를 참조 (별칭)

같은 방법을 사용하기 떄문입니다.

아래의 그림은 visual studio 에서 디버깅했을때 나오는 값입니다.

포인터와 레퍼런스 비교

포인터 p는 직접 a의 주소를 참조하고있지만 r즉 레퍼런스는 a값인 5를 그대로 가지고있습니다.
레퍼런스 r은 a의 별칭같은것으로 동일한 메모리상에 있습니다.

따라서 레퍼런스는 NULL을 참조할수가 없는것이죠

 


2. 참조 대상 할당 및 접근

 

앞서 본 NULL 허용 여부에서 알수있듯이 포인터에 할당은 &을통해 주소를 참조하게 되있습니다.

하지만 레퍼런스는 직접적으로 참조를 할수있는데 위에서 알수있듯이 레퍼런스는 선언과 동시에 참조 대상을 선언해야합니다.

 

#include<iostream>

using namespace std;

int main()
{
	int a = 5;
	int* p = &a;
	int& r; // 에러 레퍼런스는 홀로 사용이 불가능하다.
    //레퍼런스는 별칭 같은 존재이므로 반드시 별칭을 적용해줄 대상(변수) 가 필요하다
}

 

만약 위에 있는 코드처럼 선언을 안해주면 컴파일 오류가 발생합니다.

 


3. Call by pointer / Call by reference

 

매개 변수로 함수 인자 전달시

 

포인터 레퍼런스
메모리 소모 메모리 소모가 없음
값 복사가 발생함 값 복사가 발생하지 않음
함수 내에서 잘못된 연산을 할수 있다
ex : p++
NULL이 허용하지 않기 떄문에 비교적 안전하다
ex : i = NULL
매개 변수로 사용시 그 변수에 원래 값이 함수가 끝난뒤에도 변경이 되서 나간다.

이러한 차이점이 생깁니다.

또한, 함수로 인자 전달시 포인터는 반드시 Null Check 를 해주는 것이 좋습니다. 안에 NULL이 참조되있으면 매우 곤란하기 때문입니다.

'개발자 면접 공부 > C-C++' 카테고리의 다른 글

C++ 캐스팅의 종류  (0) 2022.07.14
C++ RTTI 에 대해  (0) 2022.07.14
C++ 순수 가상 함수(추상 클래스)  (0) 2022.07.12
C++ Virtual(가상) 함수  (0) 2022.07.12
댕글링 포인터(Dangling Pointer)  (0) 2022.07.11