프로그래밍/cpp

포인터와 레퍼런스,포인터의 레퍼런스,이중포인터 C++

콘파냐 2014. 5. 11. 18:43
반응형

포인터와 비슷한 개념이 레퍼런스입니다. 레퍼런스의 뜻은 이미 아시다시피 참조를 말하며, 컴퓨터공학에서 reference는 다양한 뜻을 내포하지만 오늘 설명할 개념은 C++에서 포인터와 비슷한 기능을 가진 레퍼런스와 포인터에 관해서 글을 작성합니다.

포인터는 변수의 주소값을 담는 그릇이라 생각하면, 레퍼런스는 변수의 또다른 이름을 나타냅니다. 이 둘은 각각 용량에 대한 특성을 가집니다. 포인터는 가리키는 타입에 상관없이 32비트 운영체제에서 32비트 즉 4바이트입니다. 주소값을 담기 때문에 주소만큼의 용량이죠. 모든 주소값은 같은 운영체제에서는 같을 수 밖에 없겠죠.

그럼 레퍼런스의 경우는 어떨까요? 별명이다. 용량이 없기 때문에 포인터보다 빠르다..등등 여러가지 설명이 많이 있습니다. 다 맞는 말이지만, 레퍼런스를 처음 접해서 모르는 상태에서 정확히 이해하기가 애매한 듯 보이네요. 좀 더 이해하기 쉽게 부연설명을 하자면, 레퍼런스는 레퍼런스가 가리키는 변수와 주소값을 공유하는 개념입니다. 주소값이 같단 말이죠. 아래 그림을 참고하세요.


 

B와 A는 동일하다고 보셔도 됩니다. 단 B가 참조하는 값은 처음 A로 정해졌다면 바뀔 수 없습니다. 그에 반해서 포인터는 포인터값(A의 주소값)을 다른 주소로 바꿀 수 있습니다. 

위 그림을 보시면 아시겠지만, 레퍼런스를 생성해도 메모리상에서 새로운 공간이 할당되지 않습니다. 반면에 P포인터는 4바이트가 할당되는군요. 위에서 포인터와 레퍼런스 크기에 대한 답입니다.

레퍼런스는 값을 표현할 때 연산자가 필요하지 않습니다. 그래서 깔끔한 반면에, 포인터의 경우는 *연산자가 붙는군요.

사실 프로그래밍을 하면서 레퍼런스를 많이 쓰지는 않는 것 같습니다. 생각나는 레퍼런스를 쓰는 경우는 연산자 오버로딩시에 연산자사용의 통일 성을 위해서 쓰는 것 정도 생각이 납니다. 당연히 포인터로 대체할 수 있습니다. 


간혹 *& 볼 수 있습니다. 포인터의 레퍼런스인지.. 아니면 &연산자에 다시 *연산자를 붙인건지.. 선언시에 사용되었다면 포인터의 레퍼런스를 뜻합니다. 

int *&a; //포인터의 레퍼런스

int b=3;

cout<<*&b<<endl; //*&b == b


2013/11/28 - [프로그래밍/C언어] - C언어 포인터에 대한 이해(1)


2014/01/12 - [프로그래밍/C언어] - C언어 포인터에 대한 이해(2)


2014/01/13 - [프로그래밍/C언어] - C언어 포인터에 대한 이해(3)





포인터의 레퍼런스

포인터의 레퍼런스는 이중포인터와 비슷합니다.

함수 내에서 포인터로 인수를 받는 경우는 포인터가 가리키는 값을 변경할 수 있습니다.

같은 맥락으로 이중 포인터로 인수를 받는 경우는 이중포인터가 가리키는 포인터의값과 이중포인터가 가리키는 포인터가 가리키는 값을 변경할 수 있습니다.

여기서 이중포인터 대신 포인터의 레퍼런스를 인수로 받는 경우, 레퍼런스가 가리키는 포인터의 값을 변경할 수 있습니다. 또한 레퍼런스가 가리키는 포인터가 가리키는 값의 변경도 가능합니다.



(참고 : 일종의 레벨개념으로 생각하셔서 원래값은 0Level이라 하면 0Level의 포인터나 레퍼런스는 +1Level을 해나갑니다. 함수내에서 원래값보다 높은 레벨의 변수는 원래변수의 값을 변경시킬 수 있습니다.)


*&는 사실 그렇게 중요하게 쓰이는 개념은 아니지만, 간혹 나오면 헷갈릴 수 있습니다. 어떤 변칙은 없기 때문에, 기본 개념을 바탕으로 이해하시면 됩니다.


이중포인터는 위 그림을 귀납적으로 그려보시면 이해하기 쉽습니다.



※ 참조형 타입의 한가지 장점은 메모리의 오너쉽이 어디에 있는지 명확하게 해 준다는 것이다. 참조형 타입으로 메서드에 객체를 넘겨주었을 때 메서드 내에서 객체를 헤제할 수 없기 때문이다. 포인터로 넘겨받았을 경우는 그렇지 않다. 참조형은 해제에 관련해 메서드의 역할을 명확히 해 준다. 참고: 전문가를 위한 c++ 

반응형