const는 값의 변경을 막을 때 사용된다. 하지만 const가 포인터와 함께 사용될 때는 위치에 따라 의미가 달라진다.
const는 "절대 값을 변경할 수 없다"보다는 "값을 변경하지 말라"는 의도를 나타낸다. 따라서 코드 작성 시 const를 적절히 사용하면 의도하지 않은 값의 변경을 방지하고, 코드를 더욱 명확하게 작성할 수 있다.
포인터가 가리키는 주소의 값을 변경할 수 없지만, 포인터가 가리키는 주소 자체는 변경할 수 있음
const int* pConstInt = &a; // const가 *보다 앞에 위치
// int const* pConstInt = &a; 동일한 의미를 갖고 있음
*pConstInt = 100; // 오류: 포인터가 가리키는 값 변경 불가
pConstInt = &b; // 정상: 포인터가 가리키는 주소 변경 가능
pConstInt는 "const int를 가리키는 포인터"로, 가리키는 값(*pConstInt)의 변경이 금지됨pConstInt가 다른 주소를 가리키도록 변경하는 것은 가능함포인터가 가리키는 주소 자체는 변경할 수 없지만, 가리키는 주소의 값은 변경할 수 있음
int* const pIntConst = &a; // const가 포인터 이름 뒤에 위치
*pIntConst = 400; // 정상: 포인터가 가리키는 값 변경 가능
pIntConst = &b; // 오류: 포인터가 가리키는 주소 변경 불가
pIntConst는 "주소가 고정된 포인터"로, 가리키는 값(*pIntConst)의 변경은 가능함포인터가 가리키는 주소의 값과 주소 자체 모두 변경할 수 없음
const int* const pConstIntConst = &a;
*pConstIntConst = 100; // 오류: 포인터가 가리키는 값 변경 불가
pConstIntConst = &b; // 오류: 포인터가 가리키는 주소 변경 불가
pConstIntConst는 "const int를 가리키는 const 포인터"로, 값과 주소 모두 변경할 수 없음const 키워드의 위치는 의미를 결정
const가 * 앞에 있으면: 가리키는 값의 변경 불가const가 * 뒤에 있으면: 포인터의 주소 변경 불가const가 양쪽에 모두 있으면: 값과 주소 모두 변경 불가큰 데이터(예: 구조체나 클래스 객체)는 데이터를 복사하는 것보다 복사하지 않고 원본에 직접 접근하는 것이 더 효율적이기 때문에 함수 매개변수에 포인터를 사용해서 접근하는 경우가 많다.
그러나 포인터를 사용해서 접근하면 원본 값이 변경될 수 있기 때문에 값이 변경되지 않음을 보장을 하기 위해 const를 사용하는 것이다.
void printValue(const int* pValue) {
// *pValue = 10; // 오류: 원본 값 변경 불가
std::cout << *pValue << std::endl;
}