728x90
포인터와 const
✅ const 키워드 — 상수(불변값) 선언
const int cInt = 100; // cInt는 100으로 고정된 상수
- const는 상수를 선언할 때 사용합니다.
- 일반적으로 상수는 r-value, 변수는 l-value라고 부릅니다.
int a = 10; // a는 l-value, 10은 r-value
✅ const 강제 변경 (비추천)
문법적으로는 const 변수의 값을 막고 있지만, 포인터 연산으로 강제로 변경할 수 있습니다.
const int cInt = 100;
int* pInt = (int*)&cInt;
*pInt = 300;
printf("cInt 출력 : %d\n", cInt); // 출력: 100 (변경 실패한 것처럼 보임)
왜 100이 출력될까요?
👉 레지스터 최적화 때문에 컴파일러가 cInt 값을 메모리 대신 레지스터에서 읽었기 때문입니다.
✅ volatile + const — 최적화 방지
volatile const int cInt = 100;
int* pInt = (int*)&cInt;
*pInt = 300;
printf("cInt 출력 : %d\n", cInt); // 출력: 300
🔍 volatile이란?
- 컴파일러의 최적화 방지 지시어
- 외부 요인(하드웨어, 스레드 등)으로 값이 바뀔 수 있음을 나타냄
🔸 사용 사례
- 하드웨어 레지스터
- 인터럽트 처리
- 멀티스레드 플래그 감시
volatile int flag = 0;
void waitForFlag() {
while (flag == 0) {
// volatile 덕분에 매번 메모리에서 flag를 읽음
}
}
❗주의
- volatile은 멀티스레드 동기화 보장 X
- 멀티스레드에서는 std::atomic 또는 mutex 등 병렬처리 도구 필요
✅ volatile const란?
volatile const int sensorValue = 100;
- 코드에서는 수정할 수 없지만, 외부 요인에 의해 값이 바뀔 수 있음
- 읽기 전용 하드웨어 레지스터와 같은 용도에 적합
✅ 포인터에서의 const 사용
포인터는 두 가지 측면에서 변화할 수 있습니다:
- 포인터가 가리키는 대상의 값을 바꿀 수 있는가?
- 포인터가 가리키는 주소 자체를 바꿀 수 있는가?
이 둘 중 어떤 걸 const로 막느냐에 따라 의미가 달라집니다.
1. 일반 포인터 (제약 없음)
int a = 10;
int b = 20;
int* p = &a;
*p = 15;
p = &b;
🔹 주소 변경 가능
🔹 값 변경 가능
2. const int* p — 값만 상수화
const int* p = &a;
// *p = 15; ❌
p = &b; ✅
🔹 주소 변경 가능
❌ 값 변경 불가
📌 읽을 수만 있는 포인터
3. int* const p — 주소만 상수화
int* const p = &a;
*p = 15; ✅
// p = &b; ❌
❌ 주소 변경 불가
🔹 값 변경 가능
📌 고정된 포인터
4. const int* const p — 값도, 주소도 상수화
const int* const p = &a;
// *p = 15; ❌
// p = &b; ❌
❌ 값 변경 불가
❌ 주소 변경 불가
📌 완전히 고정된 포인터
5. int const* p — const int*과 동일
int const* p = &a;
📌 const의 위치는 앞뒤 상관 없이 *을 기준으로 보면 됨
즉, const int* p == int const* p
✅ 요약표
선언 방식 | 주소 변경 | 값 변경 | 의미 요약 |
int* p | ✅ | ✅ | 자유 포인터 |
const int* p | ✅ | ❌ | 읽기 전용 값 |
int const* p | ✅ | ❌ | 읽기 전용 값 |
int* const p | ❌ | ✅ | 고정 주소 |
const int* const p | ❌ | ❌ | 완전 고정 |
✅ const로 보호된 변수, 실제로는 바꿀 수 있다?!
void Output(const int* pI) {
int i = *pI;
// 강제 변형 (비추천)
int* pInt = (int*)pI;
*pInt = 1000;
}
- 문법상 수정은 불가하지만, 강제 캐스팅으로 가능함
- 협업 시 매우 위험, 지양해야 할 코드
✅ const 사용 이유
- 복사비용이 큰 데이터의 안전한 전달
- 원본 보호
- 함수의 의도 명확히 표현 (읽기 전용)
void Output(const 자료형* pI) {
자료형 value = *pI; // 조회만 가능
// *pI = ... ❌
}
✅ 팁: 함수 파라미터 형식 확인
- 주소를 넘길 때 함수 시그니처가 헷갈리면
Ctrl + Shift + Space로 함수 인자 정보 확인 가능!
출처 : C언어/C++ 무료강의 - 31~33강
https://youtube.com/playlist?list=PL4SIC1d_ab-aOxWPucn31NHkQvNPHK1D1&si=4pBAtsXFAE7sAIRK
'C++ > 유튜브 어소트락 게임아카데미 C++무료강의' 카테고리의 다른 글
12. 문자 (0) | 2025.04.28 |
---|---|
11. void 포인터 (void*) (0) | 2025.04.19 |
9. 포인터 변수 문제 풀이 (0) | 2025.04.15 |
8. 포인터 (0) | 2025.04.15 |
7. 지역변수, 전역변수 (0) | 2025.04.02 |