const란 변동되지 않는 상수 입니다.
하지만 변수에 const를 씌운 것이기 때문에 태생은 변수입니다. 포인터로 접근하면 값을 바뀔수 있지만 컴파일러가 레지스터상에서 보호를 해줍니다. volatile 를 씌우면 휘발성 변수로 만들기 때문에 포인터로 const 변수 값을 변경할 수 있습니다.
그럼으로 절대적으로 값이 바뀌지 않는다는 맹신은 하지 말도록 합시다.
포인터 변수는 자신이 가리키는 변수를 바꿀 수 있고 가리키는 변수를 바꿀수도 있습니다. 여기서 const 를 활용하면 원본을 상수화 하거나 자신이 가리키는 변수를 바꾸지 않는 상수화를 할지 2가지 활용성이 있습니다.
이번 const 포인터는 실사용 할 때 생각나지 않을 수 있습니다. 마치 하루 빡세게 공부한다고 나중에 프로젝트에 사용할때 기억이 안날 수 있습니다. 다만 const 뒤에 오는 것이 상수가 된다는 것을 좀더 기억하시길 바랍니다.
#include <stdio.h>
#include <stdlib.h>
void Output(const int* pI) {
int i = *pI;
//*pi = &i; 가리키는 원본을 바꿀 수 없다.
// 하지만 강제 캐스팅으로 const를 깰수도 있습니다
int* c = (int*)pI;
*c = 1000;
}
int main()
{
// 1. const
const int i = 100;
// const 와 포인터
int a = 0;
int b = 0;
int* pInt = &a;
*pInt = 1;
pInt = nullptr;
//===============
//const 포인터
//===============
const int* pConstInt = &a;
//*pConstInt = 400; 불가능
pConstInt = &b;
// ===============
// 포인터 const
// ===============
int* const pIntConst = &a;
*pIntConst = 400;
//pIntConst = &b; 불가능
// 초기화 시 가리킨 대상만 가리킴, 가리키는 원본을 수정 할 수 없음.
const int* const pConstIntConst = nullptr;
int const* p = nullptr;
//*p = 100; 불가능.
{
int a = 0;
const int* pInt = &a; // 포인터가 가리키는 값을 상수화 한다는 것.
a = 100; //변수로 값 저장은 가능하다.
}
a = 100;
Output(&a);
return 0;
}
- const는 왜 사용할까요?
필요의 의해 함수에 포인터로 데이터를 참조하도록 할 수 있습니다. 하지만 포인터는 가리키는 곳을 바꿀수도 있기 때문에 포인터 주소의 값을 바꿀수 없게 상수화 시키는 용도로 사용될 수 있습니다. 또한 const를 활용하여 데이터의 원본을 수정할 의도가 없다는 내용도 내포하기 때문에 협업에도 도움이 됩니다.