ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C++_address_pointer_reference
    Programming/_C++ 2023. 7. 25. 16:30

     우리가 변수를 사용하는 것은 메모리를 사용한다는 것인데, C++에서는 포인터라는 기능을 사용하여 메모리에 저장된 변수의 위치를 사용할 수 있다. 포인터를 이해하는 것은 쉽지 않지만 이해한다면 C++ 코딩하는데 큰 도움이 될 수 있다고 생각한다.

     

    1. 메모리 & 주소 (memory & address)

     변수는 메모리에 저장되고, 변수가 메모리에 저장된 위치를 address(주소)로 나타낸다. 흔히 우리가 생각하는 집 주소, 홈페이지 주소, 이메일 주소와 같다고 생각하면 된다.

    실제로 변수를 지정하고 변수의 주소를 보면 다음과 같다.

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int a = 5;
        
        cout << "value: " << a << "\n";
        cout << "address: " << &a << "\n"; // 주소를 출력할때는 변수 앞에 &를 붙임.
        
        return 0;
    }

     

    해당 변수의 주소를 출력할 때 변수 앞에 주소 연산자(address operator) '&'을 사용하면 된다.

    실제 출력해보면, 0x로 시작하는 값이 출력되며 이는 컴퓨터의 주소라서 16진수를 사용하기 때문이다.

    주소 값은 사용하는 환경 혹은 컴퓨터에 따라 변동된다.

     

    2. 포인터 (pointer)

     pointer(포인터)는 주소를 저장하는 변수다.

    포인터는 '*'기호를 사용하고 다음과 같이 사용한다.

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int a = 5;
        int* a_pointer = &a; // int형 변수의 포인터 선언
        
        cout << "value: " << a << "\n";
        cout << "address: " << &a << "\n";
        cout << "pointer: " << a_pointer << "\n";
        
        return 0;
    }

    같은 주소값이 나오는 것을 확인할 수 있다.

     

    포인터를 통해 주소 안의 값을 확인할 때도 '*' 기호를 사용하며 이를 간접 참조 연산자 (indirection operator)라고 한다.

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int a = 5;
        int* a_pointer = &a;
        
        cout << "value: " << a << "\n";
        cout << "address: " << &a << "\n";
        cout << "pointer: " << a_pointer << "\n";
        cout << "value: " << *a_pointer << "\n";
        
        return 0;
    }

     

    3. 인수와 포인터

     그렇다면 우리가 왜 포인터를 사용해야 할까? 다음 예시를 한번 살펴보자.

    #include <iostream>
    
    using namespace std;
    
    void swap(int a, int b)
    {
        int temp = a;
        a = b;
        b = temp;
        cout << "In swap: " << "a " << a << " b " << b << endl;
    }
    
    int main()
    {
        int a = 5;
        int b = 1;
        
        swap(a, b);
        
        cout << a << " " << b;
            
        return 0;
    }

    다음과 같이 swap이라는 함수를 만들고 실행을 했을 때, swap 함수 내부에서는 a와 b의 값이 바뀌지만, 외부에서는 a와 b의 값이 바뀌지 않는다.

    이는 내부에 5와 1의 값이 복사되어 전달되어 값을 교환했을뿐, 실제로 a와 b라는 변수의 값을 교환한 것이 아니기 때문이다.

    즉, swap에는 가인수에 값이 전달되어 변경되었고, 실인수에는 영향을 미치지 않았다고 보면 된다.

    그렇다면, 실인수를 변경하기 위해서 어떻게 해야할까?

    지금과 같은 상황을 위해 포인터를 배웠다.

    #include <iostream>
    
    using namespace std;
    
    void swap(int* a, int* b)
    {
        int temp = *a;
        *a = *b;
        *b = temp;
    }
    
    int main()
    {
        int a = 5;
        int b = 1;
        
        swap(a, b);
        
        cout << a << " " << b;
            
        return 0;
    }

    이와 같이 포인터를 사용하여 직접 변수를 가르키면, 메모리 주소에 있는 변수의 값을 직접 변경하므로 우리가 원하는 결과를 얻을 수 있게 된다.

     

    포인터에 대해 한번 더 정리를 하면 다음과 같다.

    변수 int a 값을 저장
    &a a의 메모리 주소
    int* p_a = &a int형 변수 a의 주소를 저장한 p_a
    *p_a 주소를 저장한 p_a로 a의 변수를 가르킴

     

    4. 인수와 레퍼런스

     포인터는 편리하게 사용할 수 있지만, 메모리 주소를 직접 다루기 때문에 사용하기에 쉽지 않을수도 있다.

    이번에는 reference(레퍼런스)에 대해 살펴보도록 하자.

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int a = 5;
        int& r_a = a;
        
        cout << "variable: " << a << "\n";
        cout << "reference: " << r_a << "\n";
        cout << "a address: " << &a << "\n";
        cout << "ra address: " << &r_a << "\n";
            
        return 0;
    }

    출력 값을 확인해보면, a와 r_a의 값, 주소 모두 동일한 것을 볼 수 있다.

    그렇다면  일반 변수와 큰 차이가 없어보이는 reference를 왜 사용하는지 궁금할텐데 다시한번 pointer에서 했던 swap을 이번에는 reference로 보도록하자.

    #include <iostream>
    
    using namespace std;
    
    void swap(int& a, int& b)
    {
        int temp = a;
        a = b;
        b = temp;
    }
    
    int main()
    {
        int a = 5;
        int b = 1;
        
        swap(a, b);
        
        cout << a << " " << b;
            
        return 0;
    }

    swap에서 입력을 받는 부분을 이번에는 pointer가 아닌 reference로 받았는데 pointer보다 간결하게 접근할 수 있는것을 볼 수 있다.

     

    reference는 pointer와 유사하지만, 엄연히 다른 개념임을 기억하자.

    'Programming > _C++' 카테고리의 다른 글

    _C++_Smart_Pointer  (1) 2023.09.19
    C++_map  (0) 2023.07.27
    C++_function  (0) 2023.07.21
    C++_for_while_(loop statement)  (0) 2023.07.20
    C++_if (conditional statement, 조건문)  (0) 2023.07.20
Designed by Tistory.