프로그래밍 언어/C++

[C++] Pointer_pt.1

개발도사(진) 2022. 9. 26. 19:17

오늘 드디어 여태 듣기만 하던 C++의 그 유명한 포인터를 공부해 보았다. 포인터에 대한 배경 지식으로는 이전에 어디선가 주워 들었던 "주소를 지시하는 변수" 정도로만 알고 있었고, 따라서 대충 자바의 reference type 비슷한 것이 아닐까 정도로 생각하고 있었다.

 

오늘 책을 통해 학습한 포인터의 정의는 다음과 같다.

 

"일반 변수가 값을 이름붙인 양으로, 주소를 파생으로 취급하는 것과 반대로, 주소를 이름붙인 양으로 취급하고 값을 파생되는 양으로 취급하는 방식"

 

이게 한국말인가 싶었다. 야매를 좋아하는 내가 좀 더 내 식으로 풀이해서 이해한 포인터는 다음과 같다.

 

"C++에서 사용하는 변수형으로, 특정 데이터 타입의 주소를 그 값으로 하고, *을 통해 그 변수의 실제 값에 접근할 수 있는 타입"

 

여태 해 왔던 일반 변수를 선언하고 사용하는 방식과 포인터를 선언하고 사용하는 방식의 차이를 이해하는 것이 핵심이 될 것 같다. 먼저 일반 변수부터 살펴보면, 우리가 변수를 선언하고 초기화하면 컴퓨터는 메모리에 그 값을 저장하기 위한 공간을 할당하고, 16진수를 통해 그 주소를 추적한다. 가령, 

#include <iostream>

int main()
{
    using namespace std;
    
    int normalVal = 26;
    cout << normalVal << endl;
    cout << &normalVal << endl;

을 실행하면, 

26
010FFB74

라는 값을 출력한다. 여기까지는 입출력 방법이 약간 바뀌었을 뿐 자바나 다른 언어로 코딩하는 것과 다른 점이 아무것도 없다.

 

그러나 포인터는 그 이름에 담겨 있는 값은 주소이고, 실제 할당하고자 하는 값이 파생값이다. 즉 일반 변수의 상황과 반대이다. 가령,

int main()
{
    using namespace std;
    
    int normalVal = 26;
    int* pointerVal;

    pointerVal = &normalVal;

    cout << "pointerVal_이름으로 접근: " << pointerVal << endl;
    cout << "pointerVal_*으로 접근: " << *pointerVal << endl;

}

을 실행하면, 출력값은

 

pointerVal_이름으로 접근: 0055FE74
pointerVal_*으로 접근: 26

 

이다. 

 

즉 포인터를 선언하고, 포인터에 값을 할당하면, 그 포인터의 이름을 통해서 값이 저장되어있는 주소에 접근할 수 있고, *연산자를 통해 실제 그 주소에 저장되어 있는 값에 접근할 수 있다.