포인터란?
C 프로그래밍 언어에서 *p는 포인터에 저장된 값을 나타내고, p는 그 값이 위치한 주소를 나타냅니다. 이처럼 메모리 주소를 저장하는 변수를 포인터(pointer)라고 부릅니다.
const char*와 char const*는 완전히 동일한 의미로, 포인터가 상수 문자(constant char)를 가리킬 수 있다는 뜻입니다. 즉, 이 포인터가 가리키는 문자의 값은 변경할 수 없습니다. 반면 포인터 변수 자체는 상수가 아니기 때문에, 다른 상수 문자를 가리키도록 포인터의 값(주소)은 자유롭게 변경할 수 있습니다.
char* const는 포인터가 일반 문자(char)를 가리킬 수 있으며, 포인터가 가리키는 문자의 값은 변경할 수 있다는 의미입니다. 하지만 포인터 자체가 상수이므로, 한 번 초기화된 포인터는 다른 문자 변수를 가리키도록 변경할 수 없습니다.
const char* const는 포인터가 상수 문자를 가리키며, 포인터가 가리키는 값도 변경할 수 없고 포인터 자체도 변경할 수 없습니다. 즉, 값과 주소 모두 읽기 전용(read-only)입니다.
선언을 읽는 황금 법칙: 오른쪽에서 왼쪽으로
const가 포함된 포인터 선언을 해석하는 가장 쉬운 방법은 오른쪽에서 왼쪽으로 읽는 것입니다.
// 상수 문자를 가리키는 상수 포인터 const char * const // 문자를 가리키는 상수 포인터 char * const // 상수 문자를 가리키는 포인터 const char *
예제 코드 (C)
아래 예제에서 주석 처리된 잘못된 코드의 주석을 해제하고 컴파일하면, 어떤 오류가 발생하는지 직접 확인할 수 있습니다.
#include <stdio.h>
int main() {
// 예제: char const*
// 참고: char const*는 const char*와 동일합니다
const char p = 'A';
// q는 상수 문자를 가리키는 포인터
char const* q = &p;
// 잘못된 할당
// p의 값은 변경할 수 없음
// error: assignment of read-only location '*q'
//*q = 'B';
const char r = 'C';
// q는 다른 상수 문자를 가리킬 수 있음
q = &r;
printf("%c\n", *q);
// 예제: char* const
char u = 'D';
char * const t = &u;
// 가리키는 값은 변경 가능
*t = 'E';
printf("%c", *t);
// 잘못된 할당
// t 자체는 변경할 수 없음
// error: assignment of read-only variable 't'
//t = &r;
// 예제: char const* const
char const* const s = &p;
// 잘못된 할당
// s가 가리키는 값은 변경할 수 없음
// error: assignment of read-only location '*s'
// *s = 'D';
// 잘못된 할당
// s 자체도 변경할 수 없음
// error: assignment of read-only variable 's'
// s = &r;
return 0;
}실행 결과
C E