Search

const char * vs char * const

간단소개
const의 위치에 따라 정해지는 비상수/상수 포인터/데이터 정리
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
C
C++
Scrap
태그
9 more properties
const의 위치에 따라서 포인터가 상수인지 데이터가 상수인지 아니면 둘 다 상수인지 정해진다. 맨날 헷갈려해서 이참에 정리한다.
char greeting[] = "Hello"; // 비상수 포인터, 비상수 데이터 char *p = greeting; // 비상수 포인터, 상수 데이터 const char *p = greeting; // 상수 포인터, 비상수 데이터 char * const p = greeting; // 상수 포인터, 상수 데이터 const char * const p = greeting;
C++
복사
규칙이 없어 보이지만, 자세히 보면 규칙이 있다.
바로 *을 기준으로 나눠 생각하면 된다.
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; }
C++
복사
포인터가 가리키는 대상은 비상수이기 때문에, 언제든지 p가 가리키고 있는 대상을 바꿀 수 있다. 그러나 아래와 같이 동작하려고 하면 컴파일 에러가 뜰 것이다.
p[0] = 'W';
C++
복사
에러 메시지를 보면 "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; }
C++
복사
포인터가 가리키는 대상, 즉 p가 담고 있는 데이터는 비상수이기 때문에, p의 문자를 바꿀 수 있다. 그러나 포인터 자체가 상수이기 때문에 아래와 같이 사용할 수 없다.
p = world;
C++
복사

const char * const

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

Style

프로그래머마다 const를 사용하는 스타일은 조금씩 다른데, 아래와 같이 쓰는 사람들이 있다. 하지만 둘의 의미적인 차이는 전혀 없다.
// 상수 Widget 객체에 대한 포인터를 매개변수로 취함 void f1(const Widget *pw); // 동일한 의미 void f2(Widget const *pw);
C++
복사
참고:
Meyers, S. (2005) Effective C++: 55 Specific ways to improve your programs and designs. 3rd edition. Pearson Education.