본문 바로가기
Programming Language/C & C++

[C & C++] const char * vs char * const

by veggie-garden 2023. 7. 27.

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;
}

포인터가 가리키는 대상, 즉 p가 담고 있는 데이터는 비상수이기 때문에, p의 문자를 바꿀 수 있다. 그러나 포인터 자체가 상수이기 때문에 아래와 같이 사용할 수 없다.

p = world;

const char * const

포인터가 가리키는 대상과 데이터 모두 상수이기 때문에, 포인터가 가리키는 대상도 변경할 수 없으며, 데이터의 값도 변경할 수 없다.

Style

프로그래머마다 const를 사용하는 스타일은 조금씩 다른데, 아래와 같이 쓰는 사람들이 있다. 하지만 둘의 의미적인 차이는 전혀 없다.

// 상수 Widget 객체에 대한 포인터를 매개변수로 취함
void f1(const Widget *pw);

// 동일한 의미
void f2(Widget const *pw);

참고:

Meyers, S. (2005) Effective C++: 55 Specific ways to improve your programs and designs. 3rd edition. Pearson Education.

댓글