ABOUT ME

잡다한 지식들!

Today
Yesterday
Total
  • 10장. 포인터 변수란?
    C++ 기본 문법 알아보기 2019. 2. 15. 04:00

    포인터 변수?


    포인터는 변수의 타입 중에 하나이다.


    그런데 포인터 변수는 이름에서도 알 수 있듯이 다른 변수의 위치를 가리킨다.


    우리는 각자의 집에서 산다.


    집을 변수로 생각해보자.


    집 안의 가구들이나 물건들은 변수의 값이라고 생각 할 수 있다.


    집을 우리가 지금까지 배웠던 일반적인 변수라고 생각한다면 포인터 변수는 집의 주소를 담는 변수이다.


    다음은 변수의 주소를 알아보는 예제다.


    #include <iostream>

    using namespace std;


    int main()

    {

    char c = 'J';

    int i = 2;

    float f = 9.9f;



    cout << "c의 주소 = " << (int*)&c << "\n"; //int 타입 변수의 주소인 것처럼 만듬

    cout << "i의 주소 = " << &i << "\n";

    cout << "f의 주소 = " << &f << "\n";


    return 0;

    }



    비주얼 스튜디오 2017이 업데이트 되면서 밑의 콘솔 종료부분이 조금 바뀌었지만 신경쓰지 않아도 된다.


    각 변수의 주소가 잘 출력이 되는 모습을 볼 수 있다.


    이 예제를 보면 알겠지만 변수의 주소를 구하는 방법은 & 연산자를 사용하면 된다.


    이제 포인터 변수를 사용해서 주소를 출력해보자.


    #include <iostream>

    using namespace std;


    int main()

    {

    int i = 10;


    int *p;


    p = &i;


    cout << "&i = " << &i << "\n";

    cout << "p = " << p << "\n";

    cout << "&p = " << &p << "\n";


    return 0;

    }



    변수 i의 주소를 직접 출력할 때와 포인터 변수 p에 주소를 담고 출력하는 것과 결과가 같음을 볼 수 있다.


    그리고 포인터 변수 p 또한 변수이기 때문에 주소를 갖고있다.




    여러가지 타입의 포인터


    포인터 변수에 주소값을 담을 때 같은 타입의 변수 주소값만 담을 수 있다.


    포인터의 타입 이름을 만드는 규칙은 간단하다.


    포인터 변수에 담을 값의 타입을 적어주고 *를 붙여주면 된다.


    예제를 보자.


    int main()

    {

    int i = 10;

    int * pi = &i;


    char c = 'A';

    char * pc = &c;


    float f = 3.3f;

    float * pf = &f;


    bool b = true;

    bool *  pb = &b;


    short int s = 30;

    short int * ps = &s;


    return 0;

    }


    여기서 *의 띄어쓰기 방법에 대해 의문이 들 수 있다.


    int* p;


    int *p;


    int * p;


    세 가지 모두 동일한 동작을 한다.



    void 포인터


    지금까지 배운 지식으로는 포인터 변수의 타입은 담을 변수의 타입에 *를 붙이는 것이라고 배웠다.


    그런데 void 형의 변수를 본 적 있는가?


    void 포인터는 모든 타입을 가르킬 수 있는 포인터이다.


    하지만 치명적인 단점이 존재하는데, 아무것도 할 수가 없다는 것이다.


    타입에 따라 메모리에 할당되는 크기가 다르다.


    하지만 void 형식만으로는 어디부터 어디까지가 변수의 참조 영역인지 알 수가 없다.


    그래서 void 포인터는 주소만 담을 때 사용한다.


    void 포인터의 예제를 보자


    int main()

    {

    int i = 20;

    void * pv = &i;


    int * pi = (int*)pv; // 형변환을 해준 뒤 사용해야 한다.


    return 0;

    }




    주소의 값 접근하기


    포인터 변수에 주소를 담고 그 주소를 이용해 변수의 값을 바꿔보자.


    #include <iostream>

    using namespace std;


    int main()

    {

    int a = 10;

    int *p = &a;


    cout << "*p = " << *p << "\n";


    *p = 30;


    cout << "a = " << a << "\n";

    cout << "*p = " << *p << "\n";


    return 0;

    }



    값이 정상적으로 바뀐 것을 볼 수 있다.


    여기서 *, 이 연산자는 포인터 변수가 가리키고 있는 주소의 값을 의미한다.


    결국 a 변수의 값을 의미하는 것이다.


    *p를 통해서 값을 직접 바꾼 것을 알 수 있다.



    Const와 포인터


    Const란 변수의 값을 변경할 수 없게 만드는 속성이다.


    변수를 정의할 때 const를 함께 적어주면, 그 변수의 값은 다시 바꿀 수 없다.


    예제를 보고 이해하자.


    int main()

    {

    const int a = 10;


    a = 20; // 오류 발생


    return 0;

    }


    이렇게 변수의 값을 절대 바꿀 수 없다.


    그에 따른 규칙이 하나 있는데 const를 사용해서 변수를 정의할 때는 반드시 초기화 해주어야 한다는 것이다.


    이제 const와 포인터를 같이 사용해보자.


    아래의 코드는 일반적인 포인터의 사용 방법이다.


    int i1 = 1;

    int i2 = 2;

    int *p = &i1;


    p = &i2; // 에러 x

    *p = 30; // 에러 x


    이제 const를 앞에 추가해보자.


    int i1 = 1;

    int i2 = 2;

    const int *p = &i1;


    p = &i2;

    *p = 30; // 오류


    const int "*p의 뜻은 p가 가리키는 변수가 const int 타입이다." 라는 뜻이기 때문에 값의 변경을 할 수 없다.


    그렇다면 int와 const의 위치를 바꿔보자.


    int i1 = 1;

    int i2 = 2;

    const int *p = &i1;


    p = &i2; // 오류

    *p = 30;


    int const *p의 뜻은 "int 타입을 가리키는 p는 const 속성이다." 라는 뜻이기 때문에 p의 값을 바꿀 수 없다.


    다음 시간에는 복합적인 방법으로 정보를 다루는 법에 대하여 배워보자.

    'C++ 기본 문법 알아보기' 카테고리의 다른 글

    9장. 구조체에 대하여  (0) 2019.01.12
    8장. 배열에 대하여  (0) 2019.01.11
    7장. 반복문  (0) 2019.01.10
    6장. 조건문이란?  (0) 2019.01.09
    5-2장. 비트 단위 연산자와 연산자 마무리  (0) 2019.01.08
Designed by Tistory.