C#/배열

[C#]배열의 크기를 변경하는 방법

DevStory 2022. 9. 13.

배열의 크기를 변경하는 방법

C#에서 배열은 선언과 동시에 고정된 크기를 가지는 데이터입니다.

 

따라서, 배열의 크기를 벗어난 인덱스에 접근하는 경우 다음 예시처럼 IndexOutOfRangeException이 발생합니다.

class Program
{
  static void Main(string[] args)
  {
    int[] intArray = new int[3];
    intArray[4] = 40;
  }
}

[에러 내용]

배열의 크기를 벗어난 인덱스에 접근하기 위해서는 배열의 크기를 변경해야 하며, 배열의 기존 데이터는 보존되어야 합니다.

 

배열을 새로운 배열로 할당하여 배열의 크기를 변경할 수 있지만, 이 방법은 기존 데이터가 보존되지 않는다는 문제점이 존재합니다.

class Program
{
  static void Main(string[] args)
  {
    int[] intArray = { 0, 10, 20 };
    Console.WriteLine("변경 전: " + string.Join(", ", intArray));

    intArray = new int[5];
    Console.WriteLine("변경 후: " + string.Join(", ", intArray));
  }
}

[실행 결과]

변경 전: 0, 10, 20
변경 후: 0, 0, 0, 0, 0

 

다행스럽게도 C#은 배열의 크기를 변경할 수 있는 Array 클래스의 Resize() 메서드를 제공합니다. 이번 포스팅은 C#에서 배열의 크기를 변경할 수 있는 몇 가지 방법을 소개합니다.


방법 1. 반복문

첫 번째 방법으로 반복문을 사용하여 배열의 크기를 변경할 수 있습니다.

 

[배열의 크기 변경 방법]

순서 1. 제네릭 타입의 배열, 변경하고자 하는 배열의 크기를 매개변수로 가지며, 제네릭 타입의 배열을 반환하는 메서드를 정의합니다.

순서 2. 제네릭 타입의 List를 생성합니다.

순서 3. 두 번째 매개변수로 전달받은 변경하고자 하는 배열의 크기만큼 반복문을 수행하여 List에 값을 추가합니다. 이때, 기존 배열의 크기를 벗어난 경우 default 값을 추가합니다.

순서 4. List를 배열로 변환하여 반환합니다.

 

다음 예제는 int, bool 타입의 배열을 반복문을 사용하여 배열의 크기를 변경합니다.

class Program
{
  public static T[] setSizeIntArray<T>(T[] srcArray, int size)
  {
    List<T> copied = new List<T>();

    for(int loop = 0; loop < size; loop++)
    {
      if (srcArray.Length > loop)
      {
        copied.Add(srcArray[loop]);
      }
      else
      {
        copied.Add(default);
      }
    }
    
    return copied.ToArray();
  }

  static void Main(string[] args)
  {
    int[] intArray = { 0, 10, 20, 30, 40 };
    Console.WriteLine("변경 전: " + string.Join(", ", intArray));

    intArray = setSizeIntArray(intArray, 3);
    Console.WriteLine("변경 후: " + string.Join(", ", intArray));

    bool[] boolArray = { false, true, false };
    Console.WriteLine("\n변경 전: " + string.Join(", ", boolArray));

    boolArray = setSizeIntArray(boolArray, 5);
    Console.WriteLine("변경 후: " + string.Join(", ", boolArray));
  }
}

[실행 결과]

변경 전: 0, 10, 20, 30, 40
변경 후: 0, 10, 20

변경 전: False, True, False
변경 후: False, True, False, False, False

방법 2. Array 클래스의 Resize 메서드

두 번째 방법으로 Array 클래스의 Resize() 메서드를 사용하여 배열의 크기를 변경할 수 있습니다.

public static void Resize<T> (ref T[]? array, int newSize);

기존 배열을 Resize() 메서드의 첫 번째 매개변수에 전달하고 변경하고자 하는 크기를 두 번째 매개변수에 전달합니다. 주의할 점은 첫 번째 매개변수에 기존 배열을 전달할 때, 반드시 ref 키워드를 작성해야 합니다.

 

다음 예제는 int, bool 타입의 배열을 Array 클래스의 Resize() 메서드를 사용하여 배열의 크기를 변경합니다.

class Program
{
  static void Main(string[] args)
  {
    int[] intArray = { 0, 10, 20, 30, 40 };
    Console.WriteLine("변경 전: " + string.Join(", ", intArray));

    Array.Resize(ref intArray, 3);
    Console.WriteLine("변경 후: " + string.Join(", ", intArray));

    bool[] boolArray = { false, true, false };
    Console.WriteLine("\n변경 전: " + string.Join(", ", boolArray));

    Array.Resize(ref boolArray, 5);
    Console.WriteLine("변경 후: " + string.Join(", ", boolArray));
  }
}

[실행 결과]

변경 전: 0, 10, 20, 30, 40
변경 후: 0, 10, 20

변경 전: False, True, False
변경 후: False, True, False, False, False

ref 키워드

Array 클래스에서 제공하는 Resize() 메서드의 첫 번째 매개변수에 ref 키워드가 존재합니다. ref 키워드를 쉽게 이해하기 위해 다음 예제를 살펴봅시다.

 

일반적으로 매개변수를 전달하면 값만 전달되므로 메서드에서 값을 변경하더라도 기존 변수에는 아무런 영향이 없습니다.

class Program
{
  public static void setIntValue(int intParam)
  {
    intParam = 10;
  }

  static void Main(string[] args)
  {
    int intValue = 50;
    Console.WriteLine("setIntValue() 호출 전: " + intValue);

    setIntValue(intValue);
    Console.WriteLine("setIntValue() 호출 후: " + intValue);
  }
}

[실행 결과]

setIntValue() 호출 전: 50
setIntValue() 호출 후: 50

setIntValue() 메서드에서 intParam의 값을 변경하더라도 Main문에 존재하는 intValue에는 어떠한 영향이 없습니다. setIntValue() 메서드를 호출할 때, 50이라는 값만 전달하기 때문이죠.

 

하지만, ref 키워드를 사용하는 경우 setIntValue() 메서드는 Main문에 존재하는 intValue의 값을 변경합니다.

class Program
{
  public static void setIntValue(ref int intParam)
  {
    intParam = 10;
  }

  static void Main(string[] args)
  {
    int intValue = 50;
    Console.WriteLine("setIntValue() 호출 전: " + intValue);

    setIntValue(ref intValue);
    Console.WriteLine("setIntValue() 호출 후: " + intValue);
  }
}

[실행 결과]

setIntValue() 호출 전: 50
setIntValue() 호출 후: 10

ref 키워드를 사용하는 경우 setIntValue() 메서드에 값이 아닌 변수 intValue의 참조가 전달되므로 setIntValue() 메서드에서 intParam의 값을 변경하면, Main문에 존재하는 intValue도 변경된 값으로 적용됩니다.

 

즉, Array 클래스의 Resize() 메서드는 기존 배열의 크기를 조정하는 것이 아니라 크기가 변경된 새로운 배열을 할당합니다.

 

Array 클래스의 Resize() 메서드를 사용하여 int 타입인 배열의 크기를 3으로 변경하는 다음 예제를 그림으로 나타내면 다음과 같습니다.

class Program
{
  static void Main(string[] args)
  {
    int[] intArray = { 0, 10, 20, 30, 40 };

    Array.Resize(ref intArray, 3);
  }
}

[동작 과정]

[Array 클래스의 Resize() 메서드 호출 전]

[Array 클래스의 Resize() 메서드 호출 후]


정리

  • 배열의 크기를 변경하는 방법으로 반복문과 Array 클래스의 Resize() 메서드를 사용할 수 있습니다.
  • Array 클래스의 Resize() 메서드는 기존 배열의 크기를 변경하는 것이 아니라 새로운 배열을 할당합니다.
  • ref 키워드는 메서드에 값이 아니라 참조를 전달합니다.
반응형

댓글