본문 바로가기
C++/유튜브 어소트락 게임아카데미 C++무료강의

10. 포인터와 const

by GREEN나무 2025. 4. 19.
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 사용

포인터는 두 가지 측면에서 변화할 수 있습니다:

  1. 포인터가 가리키는 대상의 값을 바꿀 수 있는가?
  2. 포인터가 가리키는 주소 자체를 바꿀 수 있는가?

이 둘 중 어떤 걸 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