const의 위치에 따라서 포인터가 상수인지 데이터가 상수인지 아니면 둘 다 상수인지 정해진다. 맨날 헷갈려해서 이참에 정리한다.

char greeting[] = "Hello";

// 비상수 포인터, 비상수 데이터
char *p = greeting;

// 비상수 포인터, 상수 데이터
const char *p = greeting;

// 상수 포인터, 비상수 데이터
char * const p = greeting;

// 상수 포인터, 상수 데이터
const char * const p = greeting;

규칙이 없어 보이지만, 자세히 보면 규칙이 있다.

바로 *을 기준으로 나눠 생각하면 된다.

const 키워드가 * 왼쪽에 있으면 포인터가 가리키는 대상(데이터)이 상수이다.

const 키워드가 * 오른쪽에 있으면 포인터 자체가 상수이란 의미다.

그리고 const* 양쪽에 다 있다면 포인터가 가리키는 대상 및 포인터가 다 상수라는 의미이다.

조금 더 자세히 알아보자.

규칙

const char *

#include <iostream>

using namespace std;

int main(void) {
  char greeting[] = "Hello";
  char world[] = "World";

  const char *p = greeting;
  cout << p << endl; // 혹 cpp 처음 접하는 사람은 낯선 코드가 있다고 겁먹지 말길 바란다. 그냥 출력문이다.
  p = world;
  cout << p << endl;
}

포인터가 가리키는 대상은 비상수이기 때문에, 언제든지 p가 가리키고 있는 대상을 바꿀 수 있다. 그러나 아래와 같이 동작하려고 하면 컴파일 에러가 뜰 것이다.

p[0] = 'W';

에러 메시지를 보면 "read-only variable is not assignable", 즉 포인터 p가 가리키고 있는 대상은 상수이기 때문에 상수의 값을 변경할 수 없는 것이다.

char * const

#include <iostream>

using namespace std;

int main(void) {
  char greeting[] = "Hello";
  char world[] = "world";

  char * const p = greeting;
  cout << p << endl;
  p[0] = 'W';
  cout << p << endl;
}