돈까스 과제 - (C#) 값 타입과 참조 타입 이란 무엇인가?

2022. 12. 13. 17:41돈까스 스터디

(C#) 값 타입과 참조타입이란 무엇인가?


CTS(Common Type System) : .Net에서 동작하는 모든 프로그래밍 언어 (C#, VB.Net, J#)들이 똑같은 데이터형식을 사용하도록 해주는것

 

CLR은 참조 타입과 값 타입이라는 두 종류의 타입을 지원한다.

※ CLR(Common Language Runctime) : .Net은 코드를 실행하고 개발 프로세스를 더 쉽게 만드는 서비스를 제공하기 위해 공용 언어 런타임이라는 런타임 환경을 제공.

 

값 타입 (Value Type)

 

- 정의

값 타입은 데이터의 값을 직접 메모리 공간에 보유하고 있는 경우를 의미한다.

값 타입 변수는 스택에 할당된 메모리에 데이터의 값을 직접 포함하는 변수를 의미한다.

- 특징

  • 스택에 데이터의 값을 저장하는 것은 효율적이지만, 값 타입의 제한된 생명주기는 다른 클래스와 데이터를 공유하기에 비효율적이다.
  • 각 값 타입 변수는 데이터의 고유한 복사본을 가지고 있기 때문에(ref, out 키워드를 사용하지 않는다면) 메소드를 통해서 이 변수를 변경할 수 없다.
  • 값 타입 변수를 메소드로 통해 넘겨주게 되면 시스템은 이 변수를 복사하여 새롭게 변수를 만들게 된다.
  • 스코프를 빠져나가면 값이 스택에서 삭제된다. 

C#의 값 타입은 다음 타입으로 분리된다.

  • 단순 타입
  • 열거형 타입
  • 구조체 타입

값 타입은 System.valueType을 상속받는다.

인터페이스를 제외하고 상속받을 수 없다.


참조 타입(Reference Type)

- 정의

  값 타입과 다르게 데이터의 값을 직접 메모리에 저장하지 않는다.

  데이터의 값이 저장된 메모리를 저장한다.

  간단히 참조 타입은 데이터의 값이 들어있는 다른 메모리 공간에 대한 포인터라고 생각하면 된다.

- 특징

  • 참조 타입은 데이터 값을 힙에 저장되고 해당 데이터 값이 존재하는 힙 메모리 주소를 스택에 저장한다.
  • 참조 타입을 선언하는 것은 오버헤드가 더 크지만 다른 클래스에서 접근할 수 있다는 장점이 있다.
  • 참조 타입을 사용하면 서로 다른 변수가 같은 객체를 참조하도록 할 수 있다. 참조 타입 변수를 메소드를 통해 넘겨주게 되면 이 데이터값에 대한 새로운 복사본을 만들지 않는다. 대신 주소만 넘겨주게 된다. 만약 메소드에서 변수가 변경되면 원본 참조 타입에 영향을 준다.
  • 참조 타입 변수의 스코프를 벗어나게 되면 메모리는 바로 힙에 반환되지 않고 가비지 컬렉터가 해당 데이터가 더 이상 쓰이지 않을 때 수거하게 된다.

C# 참조 타입은 다음 타입으로 분리된다.

  • 클래스 타입
  • 인터페이스 타입
  • 배열 타입
  • 델리게이트 타입

참조 타입은 System.Object를 상속받는다.

값 타입(Value type) vs 참조 타입(Reference type)

struct와 class 차이는 무엇인가?

위에 표를 살펴보면 struct는 Value 타입이고  Class는 Renference 타입이다.

 struct는 스택으로 잡힐만한 타이밍에만 스택으로 잡히고 이게 뭔소리냐 class 안에 struct가 있으면 힙으로 잡힌다는 소리다.  고로 value 타입은 선언한 위치에 메모리가 잡히고 , Reference 힙 메모리 어딘가에 메모리가 잡힌다.

Call by value 와 Call by Reference?

Call by value는 값으로 호출하는것이고, Call by Reference는 참조로 호출하는것이다

둘의 차이점은 value는 변수의 값을 전달하고 , Reference는 변수의 주소를 전달하는것이다.

값 복사란 무엇인가?

복사에는 2가지 종류가 있다.

얕은 복사(Shallow Copy)

얕은 복사는 객체의 참조만 복사하는 것

스택에 있는 참조를 복사하게 된다.

값이 수정이 일어나도 동일한 객체를 참조하기 때문에 동일한 값이 나옴

 

깊은 복사(Deep Copy)

객체를 복사해서 새로운 객체를 만드는 것입니다.

깊은 복사는 사용자가 직접 구현해야 한다.

스택메모리 

  • 함수의 호출과 관계되는 지역 변수와 매개변수가 저장되는 영역입니다.
  • 함수의 호출과 함께 할당되며, 함수의 호출이 완료되면 소멸한다.
  • 후입 선출
  • 메모리의 높은 주소에서 낮은 주소의 방향으로 할당

힙메모리

  • 사용자가 직접 관리할 수 있는 '그리고 해야만 하는' 메모리 영역입니다.
  • 힙 영역은 사용자에 의해 메모리 공간이 동적으로 할당되고 해제된다.
  • 힙 영역은 메모리의 낮은 주소에서 높은 주소의 방향으로 할당됨

C++에서 int* pA = new int; 라고 작성했을때, x86 아키텍처 기준 힙메모리엔 몇 바이트가 할당되고 스택메모리엔 몇바이트가 할당되는가? 어떤 순서로 할당이 되는가?

동적 할당으로 힙메모리에는 4byte가 할당되고 스택메모리에는 8byte가 할당된다

순서는 개인적으로 힙에먼저 들어가고 스택에 쌓이는거같습니다.

 

메모리 파편화 : RAM에서 메모리의 공간이 작은 조각으로 나뉘어져 사용가능한 메모리가 충분히 존재하지만 할당이 불가능한 상태

 

내부 단편화 : 프로세스가 필요한 양보다 더 큰 메모리가 할당되어서 메모리 공간이 낭비 되는 상황

 

외부 단편화 : 중간중간에 생긴 사용하지 않는 메모리가 많이 존재해서 총 메모리의 공간은 충분하지만 실제로 할당할수 없는 상황

 

 

 

 

C#에서 Nullable Type 이란? 

Null 을 가질 수 없는 데이터 타입을 Null을 가질 수 있는 타입으로 만든 새로운 타입

int ,double, bool , Null이 불가능 타입들을 "값이 없다"를 표현하기 위해만듬

Sealed class

다른 클래스에서 해당 클래스에서 상속하지 못하도록 한다.  - > 실수를 줄일때 쓰면 좋을거같다.