seegongsik
프로그래밍

어떻게 값은 어디 있고 이름은 무엇을 가리키나, 메모리와 참조

프로그램이 도는 동안 우리가 만든 값은 어딘가에 꼭 들어 있어야 한다. 그 자리가 메모리다. 번호 붙은 사물함이 길게 늘어선 벽을 떠올리면 되고, 이름표는 그중 어느 칸을 가리키는 쪽지예요.

01

값은 어딘가에 들어 있다

프로그램이 도는 내내 모든 값은 메모리 어딘가에 자리를 잡는다.
메모리는 번호 붙은 사물함이 죽 늘어선 벽과 같다.
값을 하나 만들면 빈 칸 하나에 쏙 들어가고, 프로그램은 그 값을 '몇 번 칸'으로 기억해요.

칸 1
칸 2
칸 3
칸 4
칸 5

값 넣기를 누르면 빈 칸 하나에 값이 들어가고 칸 번호가 보인다.

값마다 제 칸과 번호가 생겼다.
그런데 코드에서는 '7번 칸'이라고 쓰지 않고 'a'나 '점수' 같은 이름을 쓴다.
그 이름과 칸 번호는 어떻게 이어질까요?

02

이름표는 자리를 가리킨다

이름은 값 자체가 아니라 어느 칸인지를 알고 있는 쪽지다.
이름 'a' → 3번 칸 → 그 안의 7.
그래서 'a'를 쓰면 프로그램이 쪽지를 따라가 3번 칸을 열고 7을 읽는다. 이것이 '가리킨다'는 뜻이에요.

a
→
칸 3
7

a 따라가기를 누르면 쪽지를 따라 칸으로 가서 안의 값을 꺼낸다.

이름이 칸을 가리키고, 그 칸 안에 값이 있다.
이 가리키는 쪽지를 참조라고 부른다.
여기서부터가 정말 중요하다. 'a를 b에도 준다'고 하면 무슨 일이 벌어질까요?

03

작은 값은 복사된다

숫자처럼 작은 값을 b에 주면 그 값이 새 칸에 그대로 복제된다.
이제 a는 3번 칸, b는 5번 칸으로 서로 다른 칸이다.
그래서 a를 9로 바꿔도 b는 7 그대로다. 둘은 저마다 제 값을 가진 독립된 사이예요.

a
→
칸 3
7

b에 복사 뒤 a 바꾸기를 누르면, b는 다른 칸이라 바뀌지 않는다.

복사된 작은 값은 서로 영향을 주지 않아 깔끔하다.
그런데 객체처럼 큰 것은 사정이 다르다. 큰 것을 통째로 복제하는 일은 무겁기 때문이다.
그래서 흔히 복사 대신 다른 일이 벌어져요.

04

큰 것은 같은 자리를 함께 가리킨다

객체를 b에 줄 때는 객체 전체를 복제하지 않고, 흔히 b도 같은 칸을 가리키게 한다.
이제 a와 b, 두 쪽지가 한 칸을 함께 가리킨다.
그래서 a로 그 객체를 고치면 b로 봐도 똑같이 바뀌어 있다. 한 물건에 이름이 둘이니까요.

a
↓
칸 4
객체: 1

b = a 뒤 a로 고치기를 누르면, 같은 칸이라 b로 봐도 바뀌어 있다.

두 이름이 한 칸을 가리키니 하나를 고치면 둘 다 바뀐다.
프로그램을 처음 배울 때 가장 자주 놀라는 지점이다. '왜 건드리지도 않은 b가 바뀌었지?'
이제 그 답을 안다. 같은 칸을 가리키고 있었기 때문이에요.

05

무엇을 가리키는지 알면 더는 헷갈리지 않는다

헷갈림의 정체는 언제나 하나다.
이름이 제 복사본을 가졌는가, 아니면 한 물건을 함께 가리키는가.
작은 값이면 복사라서 따로 움직이고, 큰 것이면 같은 자리를 가리켜 함께 움직인다.
이 구분만 떠올리면 놀랄 일이 없어져요.

'작은 값'과 '큰 것'을 골라 같은 일을 시키면 결과가 갈린다.

여기까지가 프로그래밍의 바탕이다.
값 하나에서 시작해 묶고, 되풀이하고, 이름 붙이고, 객체로 모으고, 디버깅으로 고치고, 기계가 돌리게 했다.
그리고 이제 그 모든 것이 어디에 들어 있고 이름이 무엇을 가리키는지까지 보았으니, 단단한 바탕이 생긴 셈이에요.

한 줄 정리값은 메모리의 한 칸(주소)에 들어 있고, 이름은 그 칸을 가리키는 쪽지다. 작은 값을 다른 이름에 주면 새 칸에 복사되어 서로 독립이지만, 큰 것(객체)은 흔히 같은 칸을 함께 가리켜서 한쪽을 고치면 다른 쪽도 같이 바뀐다. 누가 무엇을 가리키는지 알면 그 헷갈림이 풀려요.
← 프로그래밍
이 페이지가 도움 됐다면 후원하기