티스토리 뷰

C++

const 이해하기

취뽀가자!! 2020. 11. 19. 09:50

CONST

const 키워드는 변수의 값을 상수로 선언할 수 있도록 해준다. const 키워드를 사용하면 값을 변경할 수 없다. const 키워드를 사용하면 변수를 선언하게 되면 고정 기억 장치(read only memory)에 올라가게 된다.

 

포인터와 const

상수를 가리키는 포인터가 가리키는 공간은 수정할 수 없는(const) 공간이지만 상수 변수의 주소를 가리키는 포인터는 수정할 수 있는(non-const)포인터이다.

int value = 10, value2 = 4;
const int * ptr = &value;
value = 10; // ok
*ptr = 10 // not ok
printf("%d %d\n", value, *ptr); // 10 10
value = 7;
ptr = &value2;
printf("%d %d\n", value, ptr); // 7 4

앞에 const가 선언되면  const int*이 아닌 const int에 적용되기 때문에 변수 value가 상수화 되는 것이 아니다. 그렇기 때문에 포인터 변수 ptr을 이용해 가리키는 변수에 저장된 값을 변경하는 것은 안된다. 

 

포인터 변수의 상수화(상수 포인터)

위에 나왔던 포인터 const는 가리키는 값은 변경 불가능하지만 다른 변수의 주소 값으로 변경이 가능했다. 하지만 상수 포인터는 가리키는 값은 변경이 가능하지만 주소를 바꿀 수 없다.

int value = 5, value2 = 11;
int* const ptr = &value;
*ptr = 10; // ok! can change non-const value
value = 10; // ok!
printf("%d %d\n", value, *ptr); // 10 10
value = 7;
//ptr = &value2; // error! can't change pointer address
printf("%d %d\n", value, *ptr); // 7 7

 

 

ptr이 상수가 되었기 때문에 ptr이 가리키는 값은 변경이 가능하지만 ptr이 가리키는 주소값은 변경이 불가능하다.

 

상수를 가리키는 상수 포인터

이것은 앞에서 본 2가지 케이스를 모두 합한 것이다. 포인터가 가리키는 값도 상수이고 포인터 역시 상수이기에 가리키는 값과 주소값 모두 변경이 불가능하다.

 

이처럼 const의 위치에 따라 동작 방식이 달라지기에 이를 유의하며 사용하는 것이 좋다.

 

const 선언이 갖는 의미

const를 사용하면 코드의 안전성이 높아진다.

int main(){
	double PI = 3.1415;
    double rad;
    PI = 3.19 // mistake
    scanf("%lf", &rad);
    printf("%lf\n", rad*rad*PI);
    
    return 0;
}

위의 예제처럼 원의 넓이를 구하는데 원주율의 값을 실수로 변경할 수 있다. 컴파일은 이런 실수를 발견하지 못 하기에 const선언을 통해 실수를 방지한다.

 

또한 함수의 매개변수의 값을 마음대로 수정하는 것을 방지한다.

void ShowAllData(const int* arr, int len)
{
    // arr[0] = 3; 매개변수로 전달된 값을 바꾸면 가독성이 떨어질 수 있다.
    int i;
    for (i = 0; i < len; i++)
        printf("%d ", arr[i]);

}
int main(void)
{
    int arr[5] = { 1, 2, 3, 4, 5 };

    ShowAllData(arr, 4);
    return 0;
}

다음 예제는 const로 선언하여 함수의 매개변수 값이 변경되는 것을 허용하지 않고 있다. 하지만 ptr에 저장된 값을 const로 선언되지 않는 포인터 변수에 대입했다. 이렇게 되면 결국에는 ptr이 가리키는 값을 rptr을 이용하여 변경할 수 있게 된다.

void showData(const int * ptr){
    int * rptr = ptr;
    printf("%d\n", *rptr);
    *rptr = 20;
}

int main(){
    int num = 10;
    int * ptr = &num;
    showData(ptr);
    
    return 0;
}

'C++' 카테고리의 다른 글

정보은닉과 캡슐화  (0) 2019.03.03
inline 함수  (0) 2019.02.24
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함