값은 어디 있고 이름은 무엇을 가리키나, 메모리와 참조
프로그램이 도는 동안, 우리가 만든 값은 어딘가에 꼭 들어 있어야 해요. 그 자리가 바로 메모리예요. 번호 붙은 사물함이 길게 늘어선 벽이라고 생각해 봐요. 이름표는 그중 어느 칸을 가리키는 쪽지고요.
값은 어딘가에 들어 있어요
프로그램이 도는 내내,
모든 값은 메모리 어딘가에 자리를 잡아요.
메모리는 번호가 붙은 사물함이 죽 늘어선 벽 같아요.
값을 하나 만들면 빈 칸 하나에 쏙 들어가죠.
프로그램은 값을 '몇 번 칸'으로 기억해요.
'값 넣기'를 눌러 보세요. 빈 칸 하나에 값이 들어가고, 칸 번호가 보여요.
값마다 자기 칸과 번호가 생겼죠.
그런데 우리는 코드에서 '7번 칸'이라고 안 쓰잖아요?
'a', '점수' 같은 이름을 쓰죠.
그 이름과 칸 번호는 어떻게 이어질까요?
이름표는 자리를 가리켜요
이름은 값 자체가 아니에요.
'어느 칸인지'를 알고 있는 쪽지죠.
이름 'a' → 3번 칸 → 그 안의 7.
그래서 'a'를 쓰면, 프로그램이 쪽지를 따라가
3번 칸을 열어 7을 읽어요. 이게 '가리킨다'는 거예요.
이름 'a'를 눌러 보세요. 쪽지를 따라 칸으로 가서 안의 값을 꺼내요.
이름이 칸을 가리키고, 그 칸 안에 값이 있어요.
이 '가리키는 쪽지'를 참조라고 불러요.
자, 여기서부터가 진짜 중요해요.
'a를 b에도 준다'고 하면 무슨 일이 벌어질까요?
작은 값은 복사돼요
숫자 같은 작은 값을 b에 주면,
그 값이 새 칸에 그대로 복제돼요.
이제 a는 3번 칸, b는 5번 칸. 서로 다른 칸이죠.
그래서 a를 9로 바꿔도 b는 7 그대로예요.
둘은 각자 자기 값을 가진 독립된 사이예요.
'b에 복사' 뒤 'a 바꾸기'를 눌러 보세요. b는 다른 칸이라 안 바뀌어요.
복사된 작은 값은 서로 영향을 안 줘요. 깔끔하죠.
그런데 객체처럼 큰 것은 사정이 달라요.
큰 것을 통째로 복제하는 건 무겁거든요.
그래서 흔히, 복사 대신 다른 일이 벌어져요.
큰 것은 자리를 같이 가리켜요
객체를 b에 줄 때, 객체 전체를 복제하지 않고
흔히 b도 같은 칸을 가리키게 해요.
이제 a와 b, 두 쪽지가 한 칸을 함께 가리키죠.
그래서 a로 그 객체를 고치면,
b로 봐도 똑같이 바뀌어 있어요. 한 물건에 이름이 둘이니까요.
두 이름이 한 칸을 가리키니, 하나를 고치면 둘 다 변해요.
프로그램을 처음 배울 때 가장 자주 놀라는 지점이죠.
'왜 건드리지도 않은 b가 바뀌었지?'
이제 그 답을 알아요. 같은 칸을 가리키고 있었으니까요.
무엇을 가리키는지 알면, 더는 안 헷갈려요
헷갈림의 정체는 늘 하나예요.
이름이 자기 복사본을 가졌나, 한 물건을 같이 가리키나.
작은 값이면 복사라 따로 놀고,
큰 것이면 자리를 같이 가리켜 함께 움직여요.
이 구분만 떠올리면, 놀랄 일이 없어져요.
'작은 값'과 '큰 것'을 골라 같은 일을 시켜 보세요. 결과가 갈리는 게 보여요.
여기까지가 프로그래밍의 바탕이에요.
값 하나에서 시작해, 묶고 반복하고 이름 붙이고,
객체로 모으고, 디버깅으로 고치고, 기계가 돌리게 했어요.
그리고 이제, 그 모든 게 어디 들어 있고
이름이 무엇을 가리키는지까지 봤죠. 단단한 바탕이 생겼어요.