Pointer와 Const variable
const(상수)값은 그 값을 변경할 수 없다.
변경할 수 있는 값은 non-const(비상수)라고 할 수 있겠다.
#include <stdio.h>
void main(){
int value = 5;
int* ptr = &value;
*ptr = 6;
printf("%d\n", *ptr);
}
출력 : 6
하지만 value의 값이 상수인 경우에는 어떻게 될까?
#include <stdio.h>
void main(){
const int value = 5;
int* ptr = &value;
*ptr = 6;
printf("%d\n", *ptr);
}
출력 : 컴파일 에러
위 코드는 컴파일되지 않는다. 상수 변수는 값을 변경할 수 없다.
만약 상수가 아닌 포인터가 상수 변수를 가리킨 다음에 역참조하여 값을 바꿀 수 있다면, const의 의도를 위반하게 되므로 상수가 아닌 포인터는 상수 변수를 가리킬 수 없다.
물론, 종종 컴파일러에서 최적화 기능을 통해 const 한정자를 제거하고 컴파일 하는 경우도 있다. 하지만 기본적으로는 컴파일되지 않는다.
Pointer to Const 포인터 상수
const int * ptr
형식에 대한 설명이다.
이 때의 pointer는 const가 아니고, pointer가 가리키는 곳이 const이다.
즉 const int* ptr
이라는 선언은 const int를 가르키는 pointer(*)라는 의미이다.
#include <stdio.h>
void main(){
const int value = 5;
const int* ptr = &value;
*ptr = 6;
printf("%d\n", *ptr);
}
출력 : 컴파일 에러 error: assignment of read-only location
‘*ptr’ : 6 | *ptr = 6;
이번에도 마찬가지로 pointer는 const가 아니고, pointer가 가리키는 곳이 const이다.
#include <stdio.h>
void main(){
int value = 5;
const int* ptr = &value;
*ptr = 6;
printf("%d\n", *ptr);
}
출력 : 컴파일 에러 error: assignment of read-only location
‘*ptr’ : 6 | *ptr = 6;
상수 변수에 대한 포인터는 상수가 아닌 변수를 가리킬 수 있다.
상수 변수에 대한 포인터는 변수가 초기에 const로 정의되었는지에 관계 없이 포인터를 통해 접근할 때 변수를 상수로 취급한다.
따라서 포인터가 아니라 변수 그자체에서 접근은 가능하다.
#include <stdio.h>
void main(){
int value = 5;
const int* ptr = &value;
value = 6; // 포인터가 아니라 변수 그자체에서 접근은 가능하다.
printf("%d\n", *ptr);
}
출력 : 6
하지만 포인터를 통한 변수 접근은 안된다는 것이다.
#include <stdio.h>
void main(){
int value = 5;
const int* ptr = &value;
*ptr = 6; // 포인터에서의 변경은 불가능하다.
printf("%d\n", *ptr);
}
출력 : 컴파일 에러
상수를 가리키는 포인터는 상수를 가리킬 뿐, 상수 자체가 아니므로 다른 값을 가리킬 수 있다.
#include <stdio.h>
void main(){
int value1 = 5;
const int* ptr = &value1; // ptr points to a const int
int value2 = 6;
ptr = &value2; // okay, ptr now points at some other const int
printf("%d\n", *ptr);
}
출력 : 6
Const pointer 상수 포인터
int * const ptr
형식에 관한 설명이다.
포인터 자체를 상수로 만들 수 있다. 상수 포인터는 초기화 후에 가리키는 주소를 변경할 수 없는 포인터다.
상수 포인터(Const pointer) int* const (변수명)
형태로 작성한다. 즉 (변수명)이 상수라는 의미의 작성방식이다.
#include <stdio.h>
void main(){
int value = 5;
int* const ptr = &value;
printf("%d\n", *ptr);
}
일반 상수 변수와 마찬가지로 상수 포인터는 선언 시 초기화해야 한다.
즉, 상수 포인터는 항상 같은 주소를 가리킨다.
따라서 아래와 같이 코드를 작성하면 컴파일 에러가 뜬다.
#include <stdio.h>
void main(){
int value1 = 5;
int value2 = 6;
int* const ptr = &value1; // 초기화를 선언과 동시에 해야한다.
ptr = &value2; // int* const로 선언하면 주소를 변경할 수 없다.
printf("%d\n", *ptr);
}
포인터가 상수일 뿐, 가리키는 변수는 상수가 아니므로 포인터를 역참조하여 값을 변경하는 것은 가능하다.
#include <stdio.h>
void main(){
int value = 5;
int* const ptr = &value;
*ptr = 6; // 가능하다
printf("%d\n", *ptr);
}
Const pointer to a const value
포인터가 주소도 못 바꾸고 역참조 값도 못 바꾸게 하려면 const를 두번 써주면 된다.
#include <stdio.h>
void main(){
int value = 5;
const int *const ptr = &value;
printf("%d\n", *ptr);
}
상수를 가리키는 상수 포인터는 다른 주소를 가리키도록 수정할 수 없으며, 역참조를 통해 값을 수정할 수도 없다.
'Programming Tools > C++' 카테고리의 다른 글
[C++] 함수의 값, 참조, 주소 반환 (Returning values by value, reference and address) (0) | 2021.06.14 |
---|---|
[C++] Const 총 정리 - 2 (0) | 2021.06.13 |
[코드 중심 C++] - 예외 처리(Exception) (0) | 2021.05.30 |
[코드 중심 C++] - STL(Standard Template Library) (0) | 2021.05.20 |
[코드 중심 C++] - 스마트 포인터(Smart Pointer : unique_ptr, share_ptr, weak_ptr) (0) | 2021.05.19 |