Channi Studies

[C++] 상수의 포인터 (Pointers to Constants) 본문

C++/포인터 (Pointers)

[C++] 상수의 포인터 (Pointers to Constants)

Chan Lee 2023. 12. 22. 00:04

일반적인 변수에 대한 포인터를 공부하다보면,

상수 값에 대한 포인터가 궁금해질 수 있습니다.

 

const 키워드로 선언하는 상수는 알다시피 그 값이 선언과 초기화 이후에 변경할 수 없습니다.

그리고 포인터는 상수에 대한 기능도 역시 수행할 수 있습니다.

 

상수와 관련된 포인터는 총 세가지 종류로 분류할 수 있겠습니다.

  1. 상수에 대한 포인터 (pointers to constants)
  2. 상수 포인터 (constant pointers)
  3. 상수에 대한 상수 포인터 (constant pointers to constnats)

하나씩 알아보겠습니다.

 


1. 상수에 대한 포인터 (pointers to constants)

 

상수에 대한 포인터가 가르키는 데이터는 상수이고, 변경될 수 없습니다.

하지만 포인터 스스로는 변경되고 다른 값을 가르킬 수 있습니다.

 

코드로 알아보겠습니다.

int num1{100};
int num2{50};

const int *ptr1{&num1};	// pointer to constant

cout << *ptr1 << endl;

*ptr1 = 80;	// compile error
ptr1 = &num2;	// okay

 

num1의 포인터 ptr1을 const 키워드와 함께 선언한 경우, 

이를 pointers to constants 라고 칭합니다.

 

'const 선언은 포인터 앞에서 하는데 왜 상수에 대한 포인터인가요?'

하는 질문이 들 수 있을 것 같습니다.

 

일단은 ptr1의 값, 즉 가리키는 주소의 변경이 가능합니다.

값이 변경되는 건 변수지 상수가 아니겠죠?

 

그리고 예시 코드에서는 정적으로 선언된 변수에 대한 포인터여서 이러한 질문이 들 수 있을 것 같습니다.

동적으로 선언된 변수에 대한 포인터였다고 생각을 해 봅시다.

 

int *my_ptr = new int(30);
*my_ptr = 50;
cout << *my_ptr << endl;	// 50

30으로 초기화된 동적 변수에 대한 포인터 my_ptr의 예시입니다.

해당 변수가 50으로 변경 되어도 아무 문제가 없습니다.

 

const int *my_ptr = new int(30);
*my_ptr = 50;	   		// compile error
cout << *my_ptr << endl;	// 50

하지만 const로 선언된 것만 변경되었을 뿐인데 

그 값을 변경할 수가 없죠?

이런 경우를 이해하며 생각해보면 해당 질문에 대한 답이 나올 것 같습니다.

 


2. 상수 포인터 (constant pointers)

 

상수 포인터상수에 대한 포인터 와는 반대입니다.

 

스스로의 값, 즉 포인팅하는 주소값은 변경될 수 없습니다.

그리고 가리키는 주소를 다른 주소로 변경할 수도 없습니다.

하지만, 가리키고 있는 위치에 있는 값은 변경이 가능합니다.

 

  int high_score{100};
  int low_score{50};

  int *const score_ptr{&high_score};	// constant pointer

  *score_ptr = 80;		// okay
  score_ptr = &low_score;	// compile error

1번 예시와는 반대입니다.

가리키는 위치의 값은 변경되지만, 스스로가 가리키는 위치는 변경될 수 없습니다.

 


3. 상수에 대한 상수 포인터 (constant pointers to constants)

 

3번은 상수에 대한 상수 포인터입니다.

1번과 2번을 읽어봤으면 대충 예상이 되실 겁니다.

둘을 합친 것이 3번입니다.

 

즉, 가리키는 위치에 대한 변경도 불가능하고,

가리키는 위치에 있는 값도 변경이 불가능합니다.

 

int num1{100};
int num2{50};

const int *ptr1{&num1};	// pointer to constant

cout << *ptr1 << endl;

*ptr1 = 80;	// error
ptr1 = &num2;	// error