c++/기초

포인터

코드망령 2026. 5. 31. 13:09

포인터 (Pointer)

포인터(Pointer)는 메모리의 주소(Address)를 저장하는 변수이다.

일반 변수는 값을 저장하지만,

int a = 10;

포인터는 주소를 저장한다.

int* p = &a;

변수는 메모리 공간이다

int a = 10;

이 코드를 실행하면 메모리 어딘가에 공간이 생성되고 그 공간은
메모리 내 변수의 위치정보를 알리기 위한 주소를 가진다.

예시:

주소      변수      값
1000      a        10
  • 변수 이름 : a
  • 주소 : 1000
  • 값 : 10

실제 사용될 때의 주소의 형태는 다르지만 이해를 위해 주소를 1000 이라고 가정한다.


컴퓨터는 주소를 사용한다

사람이 적을때

a = 20;

컴퓨터가 하는 동작

1000번지에 저장된 값을 20으로 변경

즉, 컴퓨터 입장에서는 변수 이름보다 주소가 더 중요하다.


포인터 선언

int* p;

의 의미는

정수(int)의 주소를 저장할 수 있는 포인터 변수 p

이다.


주소 저장하기

int a = 10;

int* p = &a;

여기서

&a

a의 주소

를 의미한다.

예시:

주소      변수      값
1000      a        10
2000      p        1000

메모리 구조

p
↓
1000
↓
a
↓
10

포인터 p는 a의 주소를 저장하고 있다.


& 연산자

주소를 가져오는 연산자이다.

int a = 10;

cout << &a;

출력:

0000007FF6D1...

실제 메모리 주소가 출력된다.


* 연산자 (역참조)

포인터가 가리키는 주소의 실제 값에 접근하는 연산자이다.

int a = 10;

int* p = &a;

cout << *p;

출력:

10

왜 10이 출력될까?

주소      변수      값
1000      a        10
2000      p        1000

p는 1000을 저장하고 있다.

*p

1000번지에 있는 값

을 의미한다.

즉,

*p == a

와 같은 결과를 얻는다.


포인터로 값 변경하기

int a = 10;

int* p = &a;

*p = 20;

실행 후

주소      변수      값
1000      a        20
2000      p        1000

결과:

cout << a;

출력:

20

왜 값이 바뀔까?

*p = 20;

의 의미는

1000번지에 있는 값을 20으로 변경

하는 것이다.

즉,

a = 20;

과 동일한 효과를 가진다.


Call By Value

일반적인 함수 호출은 값을 복사한다.

void SetValue(int x)
{
    x = 20;
}

int main()
{
    int a = 10;

    SetValue(a);
}

함수 호출 시

SetValue(a);

는 실제로

int x = a;

와 비슷한 동작을 한다.


메모리 구조

main Stack Frame

주소      변수      값
1000      a        10

함수 호출 후

main Stack Frame

주소      변수      값
1000      a        10

func Stack Frame

주소      변수      값
2000      x        10

x는 a의 복사본이다.


x = 20;

을 실행하면

a = 10
x = 20

이 된다.

서로 다른 변수이므로 a는 변경되지 않는다.


이것을 Call by Value(값에 의한 호출)이라고 한다.


포인터를 사용하는 이유

원본 데이터를 직접 관리하는 것이 가능하기 때문이다.

void SetValue(int* p)
{
    *p = 20;
}

int main()
{
    int a = 10;

    SetValue(&a);
}

함수 호출

SetValue(&a);

실행 시

p = &a;

가 된다.


메모리 구조

main Stack Frame

주소      변수      값
1000      a        10
func Stack Frame

주소      변수      값
2000      p        1000

*p = 20;

실행

1000번지 값을 20으로 변경

결과

a == 20

원본 데이터가 수정된다.


Call By Reference

포인터 말고도 원본 데이터를 수정하는 방법이 있다.

void SetValue(int& x)
{
    x = 20;
}

int main()
{
    int a = 10;

    SetValue(a);
}

결과:

a == 20

참조자란?

int a = 10;

int& ref = a;

참조자는 새로운 변수가 아니다.

기존 변수의 별명(Alias)이다.


예시:

ref = 20;

실행 후

a == 20

이 된다.

ref와 a는 같은 데이터를 바라보기 때문이다.


포인터와 참조자의 차이

포인터

void func(int* p)
{
    *p = 20;
}

func(&a);

참조자

void func(int& x)
{
    x = 20;
}

func(a);

비교

구분 포인터 참조자
선언 int* p int& ref
주소 저장 O X
nullptr 가능 O X
재할당 가능 O X
사용법 *p ref
문법 복잡 간단

Call By Value / Address / Reference 비교

Call By Value

void func(int x)
  • 값 복사
  • 원본 수정 불가

Call By Address

void func(int* p)
  • 주소 전달
  • 원본 수정 가능
  • 포인터 사용

Call By Reference

void func(int& x)
  • 참조 전달
  • 원본 수정 가능
  • 문법이 간단함

핵심 정리

포인터는 메모리의 주소를 저장하는 변수이다.

int a = 10;
int* p = &a;

주소 얻기

&a

값 접근하기

*p

값 수정하기

*p = 20;

Call By Value는 값을 복사하기 때문에 원본이 변경되지 않는다.

func(a);

Call By Address는 주소를 전달하여 원본을 수정할 수 있다.

func(&a);

Call By Reference는 참조자를 사용하여 원본을 수정할 수 있다.

func(a);

포인터는 단순히 함수 인자 전달뿐 아니라

  • 동적 할당 (new)
  • 배열
  • 문자열
  • 연결 리스트
  • 트리
  • 스마트 포인터
  • 언리얼 엔진 객체 관리

등의 기반이 되는 매우 중요한 개념이다.

'c++ > 기초' 카테고리의 다른 글

#define 0 NULL  (0) 2026.06.02
참조자(Reference)  (0) 2026.05.31
매크로  (0) 2026.05.31
정적 변수  (0) 2026.05.29
오버로딩  (0) 2026.05.29