개요
- 해시테이블을 공부하다가 해시테이블은 object 데이터 타입을 반환한다고 하여 object란 무엇인가에 대해 찾아보고 공부하게 되었습니다.
object란?
- object타입은 값 형식(int, float, ...)부터 참조 형식(Class, string, ...)까지 모든 데이터를 담아낼 수 있는 데이터 타입입니다.
- 예를들면, 모든 기차가 모이는 object라는 기차역이 있고, 그 기차역에는 int형 기차, float형 기차, List기차, string기차 등 모든 종류의 기차가 올 수 있는 것입니다.
- 단, object를 제대로 이해하고 사용하기 위해선 위에서 말하는 값형식과 참조형식이 무엇인지, 박싱과 언박싱이 무엇인지 알면 좋을 것 같아 정리해보려합니다.
값? 참조?
- 값 형식(value type)은 해당 데이터를 직접적으로 스택(stack) 메모리 영역에 저장합니다.
- 참조 형식(reference type)은 데이터를 힙(heap) 메모리 영역에 저장합니다. 여기서 힙 메모리의 주소를 스택 영역에 저장합니다.
- 예제를 통해 알아보겠습니다.
값 형식(value type) 예제
int num = 2;
int num2 = num;
Debug.Log(num2);
- 출력 값은 생각하시는대로 2가 나오게 됩니다.
- 여기서 num2의 값을 10으로 다시 할당해주고, num과 num2를 출력한다면?
int num = 2;
int num2 = num;
num2 = 10;
Debug.Log("num : " + num);
Debug.Log("num2 : " + num2);
- 출력 값은 생각하시는대로 num은 2, num2는 10이 나오게 됩니다.
참조 형식(reference type) 예제
List<int> list1 = new List<int>();
list1.Add(1);
list1.Add(2);
list1.Add(3);
List<int> list2 = list1;
Debug.Log("list2의 0번방 = " + list2[0]);
- int형 데이터를 담을 수 있는 list1이라는 리스트를 생성하고 1,2,3을 순서대로 추가해줬습니다.
그리고 list2는 list1을 전달하여 생성했습니다.
그럼 list2의 0번째 방의 원소는 어떤 값이 출력될까요?
- 역시 1이 출력되었습니다.
- 그럼 이 값 형식 예제와 똑같이 list2[0]의 원소를 50으로 바꿔준 다음, list1[0]과 list2[0]을 출력해보겠습니다.
List<int> list1 = new List<int>();
list1.Add(1);
list1.Add(2);
list1.Add(3);
List<int> list2 = list1;
list2[0] = 50;
Debug.Log("list1의 0번방 = " + list1[0]);
Debug.Log("list2의 0번방 = " + list2[0]);
- 두 리스트 모두 0번방의 원소가 50으로 똑같이 나왔습니다. 차이점이 느껴지시나요?
값 형식에서는 num2의 값을 바꾸어도 num의 값은 처음에 할당한 2가 나왔지만, 참조 형식에서는 list1의 데이터를 전달받은 list2의 0번방을 바꾸니 list1의 0번방도 똑같이 바뀌었습니다. - 여기서 힙, 스택 개념이 들어가게 됩니다.
- 처음에 말씀드렸다시피 값 형식은 스택 영역에 데이터와 메모리 주소가 저장됩니다.
- int num을 선언 후 2를 할당하고, int num2는 선언 후 num 값을 할당했을 때의 스택 영역을 그림으로 표현했습니다.
- 여기서 num2의 값을 10으로 다시 할당해주면,
- num2의 값은 10으로 바뀌고, num의 값은 그대로 2입니다. 여기서 알 수 있는 것은 값 형식은 스택 영역에 데이터와 해당 데이터의 메모리 주소가 함께 저장됩니다.
- 그리고 값 형식을 선언해주면, 스택 영역에 각각의 다른 데이터 메모리 주소를 가지게 됩니다. 그래서 중간에 값을 바꿔도 다른 한 쪽에 영향을 주지 않는 것입니다.
- 쉽게 설명하자면, 집이 두 채가 있는데 한 쪽의 세입자를 바꿔도 다른 한 쪽의 세입자는 여전히 잘 살고 있는 것과 같습니다.
- 위와 다르게 참조 형식은 힙 영역에 데이터와 데이터 주소가 저장됩니다.
- list1의 데이터는 힙 영역에 저장되면서 그 데이터에 대한 주소가 생깁니다.
- list2는 list1의 데이터를 복사하였습니다. 그럼 list1이 저장된 힙 영역의 메모리 주소를 찾은 다음, 거기서 데이터를 갖다가 저장하는 것입니다.
- 쉽게 설명하자면, 이번엔 집이 한 채가 있는데 두 명이 동거를 합니다. 동거인 두 명에서 집 안의 TV, 침대, 식탁을 서로 공유합니다.
- 그런데 여기서 동거인2가 TV 어차피 안 보니까 당근마켓에 팔고, 게이밍 컴퓨터를 넣자고 합니다.
- 이렇게 되면 동거인1은 어쩌다가 TV를 잃고 게이밍 컴퓨터를 얻게 됩니다.
- 이렇듯 결국 참조 형식은 힙 영역에 데이터를 저장한 뒤 힙 영역 메모리 주소가 생깁니다. 그리고 이 힙 영역의 데이터 주소에 있는 데이터를 스택 영역의 변수들이 가져와 할당하는 것입니다.
※ 만약 제가 틀린 부분이 있으면 댓글로 조언 부탁드립니다. 그리고 박싱, 언박싱은 다음 글에서 설명 드리도록 하겠습니다. 감사합니다.
'C# > 자료구조 이해하기' 카테고리의 다른 글
C# 자료구조 트리(Tree)에 대해 알아보자 (0) | 2024.03.26 |
---|---|
C# 해시셋(HashSet)에 대해 알아보자! (0) | 2024.03.18 |
C# 해시테이블(Hash table)에 대해 알아보자! (0) | 2024.03.13 |
C# 연결리스트(Linked List)에 대해 알아보자! (0) | 2024.03.13 |
C# 오름차순과 내림차순 정렬에 대해 알아보자! (0) | 2024.03.10 |