ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 값형과 참조형
    C# 2023. 8. 24. 21:27

    I. 값형 (Value Type)

     : 변수에 값을 직접 저장하는 형식의 데이터

     : 변수가 실제 데이터를 보유함.

     : 변수를 다른 변수에 할당하거나 전달할 때 값이 복사됨.

     : 메모리의 stack 영역에 저장됨.

     

    스택 (stack)

       : 메모리에서 메서드의 호출과 관계되는 지역 변수와 매개변수가 저장되는 영역

       : 메서드의 호출과 함께 할당되며, 메서드의 호출이 끝나면 소멸됨.

     

     

     값형 데이터를 할당한 변수를 수정할 경우, 해당 변수의 값만 변경하므로, 다른 변수에 영향을 주지 않는다.
    static void Main(string[] args)
    {
        int a = 1;
        int b = a;
        Console.WriteLine($"a : {a} , b : {b}");   // a : 1 , b : 1
        b += 1;
        Console.WriteLine($"a : {a} , b : {b}");   // a : 1 , b : 2
                                // !!  b 는 a 를 복사하였지만, b의 변화가 a에 영향을 미치지 않음
    }

     

    구조체는 값형
    struct MyStruct
    {
        public int Value;
    }
    
    MyStruct struct1 = new MyStruct();
    struct1.Value = 10;
    
    MyStruct struct2 = struct1; // struct2는 struct1의 값 복사
    
    struct2.Value = 20;
    
    Console.WriteLine(struct1.Value); // 출력 결과: 10

     

    II. 참조형 (Reference Type)

      : 변수가 데이터에 대한 참조(메모리 주소)를 저장하는 형식의 데이터

      : 변수가 실제 데이터가 있는 메모리 주소를 보유함.

      : 변수를 다른 변수에 할당하거나 전달할 때 메모리 주소를 복사함.

      : 데이터(값 자체)는 힙 영역에 저장되고, 힙에 저장된 메모리 주소는 스택 영역에 저장됨.

     

    힙 (Heap)

       : 프로그램 실행 중에 동적으로 할당된 데이터와 객체가 저장되는 메모리 영역

       : 프로그램 실행 중에 가변적인 크기의 데이터를 저장하기 위해 사용

     

    참조형 데이터를 할당한 변수를 수정할 경우, 다른 변수도 동일한 메모리 주소를 공유하므로 영향을 준다.
    클래스는 참조형
    class MyClass
    {
        public int Value;
    }
    
    MyClass obj1 = new MyClass();
    obj1.Value = 10;
    
    MyClass obj2 = obj1; // obj2는 obj1과 동일한 객체를 참조
    
    obj2.Value = 20;
    
    Console.WriteLine(obj1.Value); // 출력 결과: 20

     

    III. 박싱과 언박싱

     

    박싱 (Boxing)

     : 값형을 참조형으로 변환하는 과정

     : 갑형 변수의 값을 메모리의 힙 영역에 할당된 객체로 래핑.

        

    언박싱 (Unboxing)

      : 박싱된 객체를 다시 값형으로 변환하는 과정

    using System;
    
    class Program
    {
        static void Main()
        {
            int num1 = 10;
            object obj = num1; // 박싱
            int num2 = (int)obj; // 언박싱
            Console.WriteLine("num1: " + num1); // 출력 결과: 10
            Console.WriteLine("num2: " + num2); // 출력 결과: 10
            
            List<object> myList = new List<object>(); // object 타입은 참조 형식
    
            int intValue = 10;
            myList.Add(intValue); // int를 object로 박싱하여 추가
    
            float floatValue = 3.14f;
            myList.Add(floatValue); // float를 object로 박싱하여 추가
    
            int value1 = (int)myList[0]; // object를 int로 언박싱
            float value2 = (float)myList[1]; // object를 float로 언박싱
        }
    }

     

    너무 많은 박싱과 언박싱이 일어나면, 성능 저하가 일어남.

      : 박싱을 하면서, 스택에 있는 값형식의 데이터를 복사하여 힙에 할당.

      : 언박싱을 하면서, 힙에 할당한 데이터를 다시 스택에 가져오면서, 힙에 가비지가 쌓이게 됨.

      : 그렇기 떄문에 다양한 형식을 사용해야할 경우, 제네릭을 통해 박싱/ 언박싱이 일어나지 않도록 개체의 타입을 미지 지정함.

    'C#' 카테고리의 다른 글

    델리게이트  (0) 2023.08.25
    예외 처리  (1) 2023.08.24
    인터페이스와 열거형  (0) 2023.08.24
    텍스트 던전 콘솔로 구현하기 - 작업중 학습(2)  (0) 2023.08.23
    스네이크 게임 만들기 (수정예정)  (0) 2023.08.21
Designed by Tistory.