본문 바로가기
우아한 코딩

[C#] value 타입과 reference 타입을 구분하자

by 피크인사이트 2024. 3. 8.
반응형

C# 프로그래밍에서는 변수나 객체를 사용할 때 value 타입과 reference 타입을 구분해야 합니다.

이 두 가지 타입의 차이를 이해하고 적절히 활용함으로써 메모리 사용 및 프로그램 동작에 대한 이해를 높일 수 있습니다.

이번 포스팅에서는 C#에서 value 타입과 reference 타입을 구분하는 방법과 이들 간의 차이점에 대해 알아보겠습니다

value & reference 타입


1. value 타입과 reference 타입의 개념

value 타입과 reference 타입은 C#에서 변수나 객체를 저장하는 방식을 기준으로 구분되는 두 가지 타입입니다.

 

- value 타입: 값 그 자체를 변수에 저장

변수에는 실제 값이 직접 저장되며, 변수를 다른 변수에 할당하면 값이 복사됩니다.

int, float, bool 등의 기본 데이터 형식이 value 타입에 속합니다.

 

- reference 타입: 변수에는 값이 아닌 객체에 대한 참조(reference)가 저장,

변수에는 객체의 주소가 저장되며, 변수를 다른 변수에 할당할 경우 같은 객체를 참조하게 됩니다.

클래스, 배열, 델리게이트 등이 reference 타입에 속합니다.

 

value 타입은 스택(Stack) 메모리에 할당되고, reference 타입은 힙(Heap) 메모리에 할당됩니다.

이러한 차이로 인해 메모리 할당 방식과 변수 복사 시의 동작이 다르게 이루어집니다.

 

2. 메모리 할당 방식의 차이

- value 타입: 값이 변수에 직접 저장되므로 스택(Stack) 메모리에 할당

 스택 메모리는 각 변수마다 고정된 크기의 메모리를 할당하며, 변수가 스코프를 벗어나면 해당 메모리가 해제됩니다.

 

- reference 타입: 객체의 데이터가 실제로는 힙(Heap) 메모리에 저장되고, 변수에는 객체의 주소가 저장

 힙 메모리는 자유 저장 영역(Free Store)으로서, 동적으로 할당되고 해제되는 메모리 영역입니다.

변수가 스코프를 벗어나도 객체의 주소는 유지되며, 가비지 컬렉터에 의해 메모리가 관리됩니다.

 

3. 스택(Stack), 힙(Heap) 메모리

- 스택(Stack) 메모리: 지역 변수, 매개 변수 등의 메모리 할당이 이루어지는 메모리 영역,

값 타입의 변수들이 스택 메모리에 할당됩니다.

 

- 힙(Heap) 메모리: 동적으로 할당되고 해제되는 메모리 영역으로  키워드 new 를 사용하여 객체 생성 시 힙 메모리에 할당되며, reference 타입의 변수들이 힙 메모리에 할당됩니다.

 

이러한 메모리 할당 방식의 차이로 인해 value 타입과 reference 타입은 메모리 사용 방식과 동작 방식에서 차이가 발생하며, 이를 이해하는 것이 프로그래밍에서 중요합니다.

 

4. 복사 시 동작 방식

- value 타입: 변수를 다른 변수에 할당할 때 값이 복사

 두 변수는 각각의 값을 가지고 있으며, 한 변수의 값을 변경해도 다른 변수에는 영향을 주지 않습니다.

 

- reference 타입: 변수를 다른 변수에 할당할 때 객체의 주소가 복사

 두 변수는 같은 객체를 참조하게 되며, 한 변수를 통해 객체의 내부 상태를 변경하면 다른 변수를 통해서도 변경된 상태를 확인할 수 있습니다.

 

5. 메서드 호출 시 동작 방식

- value 타입: 메서드에 value 타입의 변수를 전달할 때는 변수의 값이 복사되어 전달

 메서드 내에서 변수의 값이 변경되어도 호출하는 쪽의 변수에는 영향을 주지 않습니다.

 

- reference 타입: 메서드에 reference 타입의 변수를 전달할 때는 객체의 주소가 복사되어 전달

 메서드 내에서 객체의 내부 상태를 변경하면 호출하는 쪽의 변수에도 변경된 상태가 반영됩니다.

 

6. 예시 코드와 실제 활용

// value 타입의 예시 (구조체)
struct Point
{
 public int X;
 public int Y;
}

void ModifyValue(Point point)
{
 point.X = 10;
 point.Y = 20;
}

Point valuePoint = new Point { X = 5, Y = 5 };
ModifyValue(valuePoint);
Console.WriteLine($"X: {valuePoint.X}, Y: {valuePoint.Y}"); // 출력: "X: 5, Y: 5"

// reference 타입의 예시 (클래스)
class MyClass
{
 public int Value;
}

void ModifyReference(MyClass myClass)
{
 myClass.Value = 10;
}

MyClass referenceObject = new MyClass();
referenceObject.Value = 5;
ModifyReference(referenceObject);
Console.WriteLine($"Value: {referenceObject.Value}"); // 출력: "Value: 10"

 

위 코드에서는 value 타입과 reference 타입의 동작 방식을 비교하기 위한 예시 코드를 제공합니다.

value 타입인 구조체와 reference 타입인 클래스를 각각 사용하여 메서드 호출 시 동작 방식을 확인하고, 그에 따른 결과를 출력합니다.


마치며

이번 포스팅에서는 C# 프로그래밍에서 value 타입과 reference 타입을 구분하는 방법과 이들 간의 차이점에 대해 알아보았습니다.

value 타입과 reference 타입을 구분하는 것은 프로그래밍에서 중요한 개념 중 하나입니다.

이를 이해하고 적절히 활용함으로써 메모리 사용을 최적화하고 프로그램의 동작을 더욱 효율적으로 제어할 수 있습니다.

 

앞으로는 value 타입과 reference 타입을 구분하여 적절히 활용하는 것뿐만 아니라, 메모리 사용에 대한 더 깊은 이해와 관련된 고급 주제를 학습하는 것도 필요해 보입니다

 메모리 관리, 가비지 컬렉션, 스택과 힙 메모리의 세부 동작 등을 학습하면 프로그램을 더욱 효율적으로 개발할 수 있을 것이라 생각합니다.

감사합니다.

반응형