본문 바로가기
Language/C#

[c#]Array 얕은복사와 깊은복사

by ninanio3 2021. 12. 11.

이번에는 Array의 얕은 복사와 깊은 복사에 대해서 알아본다.
기본적으로 배열은 참조타입이다.
연산자 = 을 사용하게 되면 얕은 복사(shallow copy)가 이뤄진다. 
Array.Copy()를 사용하게 되면 깊은 복사(deep copy)가 이뤄진다.

Array.Copy(
딱 여기까지 찍으면 4개의 method가 나온다.(참고로 괄호를 열거나, 점을 찍으면 사용할 수 있는 함수들이 나온다.

1 of 4   void Array.Copy(Array sourceArray, Array destinationArray, int length)
2 of 4   void Array.Copy(Array sourceArray, Array destinationArray, long length)
3 of 4   void Array.Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length)
4 of 4   void Array.Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, long length)

1번째 2번째의 method에서는
일단, 수정 전 배열을 넣으라고 한다. sourceArray이다.
둘째로, 수정할 배열을 넣으라고 한다. destinationArray이다.(직역하자면, 목적 배열 정도? 무엇을 넣을거냐!)
셋째로 길이를 정하라고 한다.
그러니깐 말로 풀어서 설명하자면 배열 sourceArray를 destinationArray에 length만큼 일대일 복사한다.

3번째, 4번째의 method에서 SourceIndex를 통해서 소스 인덱스를 지정할 수도 있다.


처음에 c#을 공부했을 때, 얕은복사와 깊은복사의 차이를 잘 몰랐다. 그냥 '='을 넣어주면 a = b처럼 a에 b가 얹어지는게 아닌가 하는 생각이 들었다. 하지만, 이번에 코딩연습을 해보고 포스팅을 하면서 개념이 정리되는 것 같다. 얕은 복사와 깊은 복사는 복사를 할 때 클래스 단위로 바뀌는 것 같다. 얕은 복사를 클래스 내에서 바로 print도 해보고, 클래스를 벗어나서 print 해보면 그 차이를 바로 알 수 있다.




 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HEK_Exer;
/*
 * 문제 내용 : 배열A와 배열B를 서로 바꿔보자.
 * 학습 내용 : Array.Copy()를 이용한 깊은 복사를 이해한다.
 * 힌트 내용 : 배열은 참조타입이다. 대입 연산자 = 을 사용하면 주소에 의한 복사로 얕은 복사가 된다.
 * */

namespace HEK_Exercise
{
    public class Program
    {
        static void Main(string[] args)
        {
            HEK_Exer.HEK_Exer Exer = new HEK_Exer.HEK_Exer();

            int[] aa = { 1, 3, 5, 7, 9 };
            int[] bb = { 2, 4, 6, 8, 10 };
            int[] cc = { 1, 2, 3, 4, 5 };
                       
            Exer.shallow1(aa, bb);
            Exer.print(aa);
            Exer.shallow2(aa, bb);
            Exer.deep(bb, cc);
            Exer.print(bb);
        }
    }
}




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HEK_Exer
{
    public class HEK_Exer
    {
        public void shallow1(int[] aa, int[] bb)
        {
            int[] temp;
            temp = aa;
            aa = bb;
            bb = temp;
            Console.Write("얕은 복사를 클래스를 벗어나 출력합니다." + "\n");
        }
        public void shallow2(int[] aa, int[] bb)
        {
            int[] temp;
            temp = aa; //aa의 값을 temp에 집어넣음
            aa = bb;    //bb의 값을 aa에 넣음. 그러면 aa는 {2,4,6,8,10}이 나온다.
            bb = temp;
            Console.Write("얕은복사를 클래스 안에서 출력합니다." + "\n");
            print(aa); //aa의 결과값 확인
        }
        public void deep(int[] bb, int[] cc)
        {
            int count = bb.Length;
            int[] temp1 = new int[count];
            Array.Copy(bb, temp1, count);   //bb의 값은 {2,4,6,8,10}이다.
            Array.Copy(cc, bb, count);      //여기서 bb의 값이 {1,2,3,4,5}로 바뀐다.
            Array.Copy(temp1, cc, count);
            Console.Write("깊은복사를 클래스를 벗어나 출력합니다." + "\n");
        }
        public void print(int[] a)
        {
            for (int i = 0; i < a.Length; i++)
            {
                Console.Write(a[i] + " ");
            }
            Console.WriteLine();
        }
    }
}