본문 바로가기
프로그래밍 언어/cpp

[C++] 상수(const)와 포인터

by TyT. 2023. 2. 8.
반응형

상수 (const)

변수와 대조적으로 변하지 않는 수. 상수선언은 const를 붙여서 선언해 준다.

const int a = 1;

일반적인 방법으로 상수를 변경할 수 없다.

#include <stdio.h>


void main() 
{
    const int a = 1;
    a = 2;
}

 

lvalue는 변수를 말한다. rvalue는 상수.

상수를 변경하려 하면 문법적 오류가 뜨며 컴파일아 안되는 것을 확인할 수 있다. 하지만 포인터로 접근하게 되면 상수로 선언된 값도 변경이 가능하다.

#include <stdio.h>


void main() 
{
    const int a = 1;
    int* p = (int*)&a;

    *p = 2;

    printf("%d", a);

}

 

상수의 값을 변경하지만 실행이 된것을 확인할 수 있다. 하지만 출력값이 변하지 않았다. 이는 내부적으로 프로그램이 메모리를 직접참조하지 않고 상수라 선언된 값은 바뀌지 않았을거라 판단해 레지스터를 업데이트하지않고 그대로 참조해 사용하였기 때문에 1이 출력된 것이다. 이럴땐 volatile을 사용하면 된다.(레지스터 최적화를 사용하지 않겠다는 선언이라는 것 같다.)

#include <stdio.h>


void main() 
{
    volatile const int a = 1;
    int* p = (int*)&a;

    *p = 2;

    printf("%d", a);

}

 

값이 바뀐걸 확인할 수 있다. 하지만 상수로 선언된 값은 되도록이면 상수로만 사용 하도록 하자. 바꿀 수는 있지만, 바꿀일이 있는 값이라면 변수로 선언하는게 문법적으로 자연스럽다. 어디까지나 바뀔수 있음을 보여준 것 뿐이다.

const와 포인터


포인터에 대해서는 포인터와 포인터가 가리키는 변수에 대해 상수화 할 수 있겠다.

#include <stdio.h>


void main() 
{
    int a = 1;
    int b = 2;

    const int* p1 = &a;
    p1 = &b;
    // *p1 = 3;    //불가능. 포인터가 가리키는 변수가 상수화 되었기 때문

    int* const p2 = &a;
    *p2 = 3;
    //p1 = &b;    //불가능. 포인터 변수가 상수화 되었기 때문

    const int* const p3 = &a;
    //p3 = &b;
    //*p3 = 3;    //둘 다 불가능. 포인터 변수와 포인터가 가리키는 변수 또한 상수화 되었기 때문

    printf("a: %d\n", a);
    printf("b: %d\n", b);
    printf("*p1: %d\n", *p1);
    printf("*p2: %d", *p2);
}

 

위 코드에서 주석부분을 제거해보며 실행해 보면 차이점을 알 수 있다.

상수화에 대해서, 말이 상수지 실제론 변경이 가능하다는 점 등 유의할 점이 많은것 같다. const기호를 사용할땐 주의를 기울이도록 하자.

반응형