포인터는 주소를 저장한다 — 그렇다면 왜 타입이 있나요?

발행: (2025년 12월 23일 오후 02:38 GMT+9)
4 min read
원문: Dev.to

Source: Dev.to

포인터에 타입이 있는 이유

우리는 종종 포인터는 메모리 주소를 저장하는 변수일 뿐이다 라는 말을 듣습니다.
이 말은 기술적으로 맞지만 완전하지는 않습니다. 포인터가 단순히 원시 주소만이라면, 모든 포인터는 동일할 것입니다(보통 4바이트 또는 8바이트). C/C++에서는 char*, int*, double*, struct* 등 다양한 포인터 타입이 존재합니다.

주소가 단지 숫자라면, 타입이 왜 중요한 걸까요?

포인터 타입의 역할

물리 메모리는 정수, 문자, 부동소수점 숫자를 구분하지 않습니다; 단순히 바이트들의 연속일 뿐입니다. 포인터 타입은 컴파일러에게 두 가지 중요한 정보를 제공하는 템플릿 역할을 합니다:

  1. – 해당 주소에서 시작해 몇 바이트를 읽을지.
  2. 해석 – 읽어들인 바이트들을 어떻게 취급할지(예: 부호 있는 정수, IEEE‑754 부동소수점, ASCII 문자 등).

예시 시각화

주소 0x20000000부터 시작하는 네 바이트 메모리를 살펴보겠습니다:

주소
0x200000000x01
0x200000010x02
0x200000020x03
0x200000030x04

char* 역참조

char *pc = (char *)0x20000000;
char c = *pc;   // 1 바이트를 읽음

컴파일러는 정확히 한 바이트(0x01)를 읽고 이를 문자로 해석합니다.

int* 역참조

int *pi = (int *)0x20000000;
int i = *pi;   // 4 바이트를 읽음

컴파일러는 다음 네 바이트를 읽어 작은 엔디안 시스템에서는 0x04030201이라는 정수값으로 결합합니다.

주소와 그 아래에 있는 데이터 자체는 변하지 않으며, 해석만 달라집니다.

메모리와 포인터에 관한 기본 진리

  • 메모리는 바이트 단위 저장소로 이루어진 선형 주소 공간이다.
  • 주소는 단지 시작점일 뿐이다.
  • 포인터 타입은 컴파일러에게 그 주소에 있는 바이트들을 어떻게 해석할지 알려준다.

메모리 자체는 타입 개념이 없기 때문에, 포인터 타입은 매우 중요해집니다. 컴파일러에 다음을 알려줍니다:

  1. 읽거나 쓸 바이트 수.
  2. 그 바이트들을 어떻게 해석할지.
  3. 포인터 연산이 어떻게 동작해야 하는지.

포인터 연산과 타입 스케일링

포인터 연산은 가리키는 대상 타입의 크기에 따라 스케일됩니다. 예를 들어:

int *p;
p = /* some address */;
p + 1;   // sizeof(int) == 4 이므로 4 바이트 앞으로 이동

만약 pchar*라면 p + 1은 한 바이트만 이동합니다.

“포인터는 주소를 저장한다”는 사실은 첫 번째 단계일 뿐입니다. 포인터 타입을 이해하면 소프트웨어가 메모리와 실제로 어떻게 소통하는지 알 수 있습니다.

Back to Blog

관련 글

더 보기 »