C언어 포인터 개념 (*, &)
포인터는 C언어의 핵심이자 메모리에 직접 접근할 수 있는 강력한 도구다. 게임 클라이언트 및 엔진 레벨에서는 성능 최적화와 메모리 관리를 위해 포인터의 이해가 필수적이다.
1. 포인터의 기본 개념
포인터는 메모리 주소를 저장하는 변수다. 일반적인 변수가 '값'을 저장한다면, 포인터 변수는 그 값이 위치한 '메모리 상의 주소'를 저장한다.
주소 연산자 (&)
- 변수 앞에 붙여 해당 변수의 시작 주소값을 추출한다.
- C++의 참조자(Reference)와 기호는 같으나 포인터 문맥에서는 주소 추출의 기능을 수행한다.
역참조 연산자 (*)
- 포인터 변수 앞에 붙여 해당 주소에 저장된 값에 접근한다.
- "이 주소로 가서 데이터를 읽거나 써라"라는 의미다.
2. 언어별 포인터와 메모리 접근
C / C++
- 직접 제어: 메모리 주소에 직접 접근하고 연산할 수 있다.
- 포인터 연산:
ptr + 1과 같은 연산이 가능하며, 이는 자료형의 크기만큼 주소를 이동시킨다. - 유연성과 위험성: 메모리 누수(Memory Leak)나 댕글링 포인터(Dangling Pointer) 문제가 발생할 수 있어 수동 관리가 중요하다.
- C++의 차이점: C++에서는 포인터 외에도
&를 이용한 참조자(Reference)를 지원하여 포인터의 위험성을 일부 완화한다.
Python
- 추상화: C언어 스타일의 명시적인 포인터 개념이 없다.
- 모든 것이 객체: 모든 변수는 객체에 대한 참조(Reference)를 저장한다. 내부적으로는 포인터를 사용하지만 개발자가 직접 주소를 계산하거나 역참조 연산자를 사용할 수 없다.
- 가비지 컬렉터(GC): 메모리 할당과 해제를 언어 차원에서 자동으로 관리한다.
3. 포인터의 성능과 시간 복잡도
| 구분 | 내용 | 비고 |
|---|---|---|
| 접근 속도 | O(1) | 주소를 알고 있다면 즉시 데이터에 접근 가능 |
| 공간 효율 | 시스템 아키텍처 의존 | 32bit는 4byte, 64bit는 8byte 고정 크기 |
| 데이터 전달 | 값 복사 vs 주소 전달 | 대규모 구조체 전달 시 주소만 넘기는 것이 압도적으로 유리 |
4. 면접 핵심 질문 대비 (CS 포인트)
Call by Value vs Call by Address (Pointer)
- Call by Value: 인자로 전달되는 값을 복사한다. 함수 내부에서 값을 바꿔도 원본은 변하지 않는다. 복사 비용이 발생한다.
- Call by Address: 주소값을 복사하여 전달한다. 함수 내부에서 주소를 통해 원본 데이터에 직접 접근하므로 원본 수정이 가능하다. 큰 데이터를 다룰 때 성능상 이점이 크다.
포인터와 배열의 차이
- 배열: 이름 자체가 첫 번째 요소의 주소를 나타내는 상수 포인터와 유사하다. 할당된 메모리 크기를 유지한다.
- 포인터: 주소값을 변경할 수 있는 변수다. 배열의 시작 주소를 담을 수 있지만,
sizeof연산 시 배열 전체 크기가 아닌 포인터 자체의 크기(8byte 등)만 반환한다.
왜 게임 프로그래밍에서 포인터가 중요한가?
게임은 실시간으로 방대한 데이터를 처리해야 한다. 수만 개의 오브젝트 데이터를 매 프레임 복사(Call by Value)하는 것은 성능 재앙을 초래한다. 포인터를 통해 데이터의 위치만 전달함으로써 메모리 대역폭을 절약하고 CPU 캐시 효율을 극대화할 수 있다.
5. 포인터 비유: 보물찾기 지도
포인터를 이해하기 가장 쉬운 비유는 '지도'와 '보물'이다.
- 변수: 보물 상자 그 자체.
- 값: 보물 상자 안에 든 금괴.
- 주소 (&): 보물 상자가 묻혀 있는 위도와 경도.
- 포인터: 위도와 경도가 적혀 있는 지도(쪽지).
- 역참조 (*): 지도를 보고 해당 좌표로 찾아가서 상자를 열어보는 행위.
만약 친구에게 보물을 보여주고 싶을 때, 무거운 보물 상자를 통째로 들고 가는 것(Call by Value)보다 좌표가 적힌 종이 한 장을 건네주는 것(Call by Address)이 훨씬 효율적인 것과 같다.
'학습 일지 > C' 카테고리의 다른 글
| Windows11 Docker + DevContainer Ubuntu 환경 구축 (0) | 2026.04.22 |
|---|---|
| 동적 메모리 할당 (0) | 2026.04.09 |
| [VSC] C 소스 코드 실행 파일 이름 변경 (0) | 2026.04.03 |
| trigraph ??! ignored, use -trigraphs to enable [-Wtrigraphs] 해결 (0) | 2026.04.03 |