List와 Array는 하나의 변수가 아닌 여러 개의 변수를 담을 수 있다는 점에서 공통점이 있습니다. 하지만 서로의 특성을 잘 알지 못하는 상태로 쓰다보면 리스트를 써야하는 상황에 배열을 쓰게 되고, 그 반대의 상황이 나오기도 합니다. 이러한 상황이 생길 경우 리스트를 사용하면 쉽게 해결된 문제를 배열을 사용하여 오랜 시간동안 해결 해야하는 문제가 되기도 합니다. 그렇기 때문에 두 자료형의 특성을 잘 알고 상황에 맞게 써야 합니다. 이번 시간은 List와 Array의 차이와 용도를 알아 보겠습니다.


[리스트의 개념]

데이터를 저장하는 데 사용되는 유용한 자료 구조입니다. 리스트는 여러 값을 포함할 수 있는 컬렉션입니다. 배열과 유사하지만 크기가 동적으로 조정될 수 있습니다.


[리스트의 사용법과 예시코드]

생성: 리스트를 생성하려면 List<T> 클래스를 사용하고, T는 리스트에 저장될 요소의 형식을 나타냅니다.

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        // 정수를 저장할 리스트 생성
        List<int> numbers = new List<int>();

        // 문자열을 저장할 리스트 생성
        List<string> names = new List<string>();
    }
}

요소 추가: Add 메서드를 사용하여 리스트에 새로운 요소를 추가할 수 있습니다.

numbers.Add(10);
numbers.Add(20);
numbers.Add(30);

names.Add("Alice");
names.Add("Bob");
names. Add("Charlie");

요소 접근: 리스트의 각 요소에는 인덱스를 사용하여 접근할 수 있습니다.

int firstNumber = numbers[0]; // 첫 번째 요소에 접근
string secondName = names[1]; // 두 번째 요소에 접근

요소 제거: Remove 메서드를 사용하여 리스트에서 특정 요소를 제거할 수 있습니다.

numbers.Remove(20); // 값이 20인 요소 제거
names.RemoveAt(0);  // 첫 번째 요소 제거

반복: foreach 루프를 사용하여 리스트의 모든 요소에 접근할 수 있습니다.

foreach (int num in numbers)
{
    Console.WriteLine(num);
}

foreach (string name in names)
{
    Console.WriteLine(name);
}

[리스트의 특성]

  1. 동적 크기: 리스트는 배열과 달리 크기가 동적으로 조절됩니다. 이는 요소를 추가하거나 제거할 때 자동으로 크기가 조정됨을 의미합니다. 크기를 직접 관리할 필요 없이 요소를 유연하게 추가하고 제거할 수 있습니다.
  2. 제네릭 타입: 제네릭(Generic) 클래스이므로 여러 가지 데이터 형식을 저장할 수 있습니다. List<T> 형태로 사용되며, T는 리스트에 저장될 요소의 형식을 나타냅니다. 예를 들어, List<int>는 정수를 저장하는 리스트를 의미하고, List<string>은 문자열을 저장하는 리스트를 의미합니다.
  3. 인덱스 기반 접근: 각 요소는 인덱스를 사용하여 접근할 수 있습니다. 이는 배열과 유사하며, 인덱스를 사용하여 요소를 읽거나 수정할 수 있습니다. 예를 들어, numbers[0]은 리스트의 첫 번째 요소를 나타냅니다.
  4. 편리한 메서드: 다양한 메서드를 제공하여 요소를 추가, 제거, 검색하는 등의 작업을 수행할 수 있습니다. Add(), Remove(), Clear(), Contains() 등의 메서드를 사용하여 리스트를 다룰 수 있습니다.
  5. 반복 가능(Iterable): foreach 루프를 사용하여 각 요소에 접근할 수 있습니다. 이를 통해 리스트의 모든 요소를 쉽게 반복하고 처리할 수 있습니다.
  6. 가변적인 데이터 구조: 가변적인 데이터 구조이므로 요소를 추가하거나 제거하는 데 시간이 걸릴 수 있습니다. 이는 리스트의 크기가 동적으로 조절되기 때문에 발생합니다. 따라서 많은 요소를 추가하거나 제거해야 하는 경우에는 성능에 영향을 끼칩니다.

[배열의 개념]

동일한 데이터 형식의 요소들을 순차적으로 저장하는 선형 자료 구조입니다. C#에서 배열은 고정된 크기를 갖는 데이터 컨테이너로, 여러 값을 하나의 변수에 저장하고 관리할 수 있습니다.


[배열의 사용법과 예시코드]

생성: 특정 데이터 형식과 크기를 지정하여 생성됩니다.

// 정수형 배열 생성
int[] numbers = new int[5]; // 길이가 5인 정수형 배열 생성

// 문자열 배열 생성
string[] names = new string[3]; // 길이가 3인 문자열 배열 생성

요소에 값 할당: 요소에 값을 할당할 때는 인덱스를 사용합니다.

numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
numbers[3] = 40;
numbers[4] = 50;

names[0] = "Alice";
names[1] = "Bob";
names[2] = "Charlie";

요소에 접근: 각 요소에는 인덱스를 사용하여 접근할 수 있습니다.

int firstNumber = numbers[0]; // 첫 번째 요소에 접근
string secondName = names[1]; // 두 번째 요소에 접근

길이 확인: 배열의 길이는 Length 속성을 통해 확인할 수 있습니다.

int lengthOfNumbers = numbers.Length; // numbers 배열의 길이는 5
int lengthOfNames = names.Length; // names 배열의 길이는 3

반복: for 루프를 사용하여 배열의 모든 요소에 접근할 수 있습니다.

for (int i = 0; i < numbers.Length; i++)
{
    Console.WriteLine(numbers[i]);
}

for (int i = 0; i < names.Length; i++)
{
    Console.WriteLine(names[i]);
}

[배열의 특성]

  1. 고정된 크기: 배열은 생성될 때에 지정된 크기를 가지며, 이 크기는 변경할 수 없습니다. 이는 배열에 저장되는 요소의 개수가 고정되어 있음을 의미합니다. 크기를 변경하려면 새로운 배열을 생성하고 데이터를 복사해야 합니다.
  2. 인덱스 기반 접근: 각 요소는 고유한 인덱스를 갖습니다. 이 인덱스를 사용하여 특정 요소에 접근할 수 있습니다. 인덱스는 0부터 시작하여 배열의 길이보다 하나 작은 값까지의 범위를 갖습니다.
  3. 단순하고 효율적인 구조: 메모리에서 연속된 공간에 요소들을 저장합니다. 따라서 요소에 접근할 때 메모리 접근이 효율적입니다. 이는 배열의 요소에 대한 빠른 접근 및 조작을 가능하게 합니다.
  4. 단일 데이터 형식: 동일한 데이터 형식의 요소들을 저장합니다. 즉, 모든 요소가 동일한 데이터 형식을 가져야 합니다. 예를 들어, int 형식의 배열은 정수형 데이터만을 저장할 수 있습니다.
  5. 메모리 할당: 한 번에 메모리에 할당됩니다. 이는 정적으로 크기가 결정되므로 추가적인 메모리 할당이나 해제가 발생하지 않습니다.
  6. 다차원 배열: C#에서는 단순한 1차원 배열뿐만 아니라 다차원 배열도 지원됩니다. 이는 행렬이나 다중 인덱스를 사용해 데이터를 구조화하는 데 유용합니다.

[리스트와 배열의 차이점]

  1. 크기의 유연성:
    • 배열(Array): 생성될 때 크기가 고정됩니다. 크기를 변경하려면 새로운 배열을 생성하고 데이터를 복사해야 합니다. 따라서 배열은 크기가 변경되지 않고 고정되어 있습니다.
    • 리스트(List): 동적으로 크기가 조절됩니다. 요소를 추가하거나 제거할 때 크기가 자동으로 조정됩니다. 이는 데이터를 유연하게 관리할 수 있도록 해줍니다.
  2. 메모리 할당 및 해제:
    • 배열(Array): 배열은 한 번에 메모리에 할당됩니다. 크기가 고정되어 있으므로 메모리 할당 및 해제가 발생하지 않습니다.
    • 리스트(List): 동적으로 크기가 조절되므로 메모리 할당 및 해제가 필요할 수 있습니다. 크기가 변경될 때마다 메모리를 다시 할당하고 요소를 복사해야 할 수 있습니다.
  3. 요소의 삽입 및 삭제:
    • 배열(Array): 요소를 삽입하거나 삭제하는 것은 비용이 많이 들 수 있습니다. 특히 중간에 요소를 삽입하거나 삭제할 경우에는 나머지 요소를 이동시켜야 합니다.
    • 리스트(List): 요소를 삽입하거나 삭제하는 데 효율적입니다. 동적으로 크기가 조절되므로 중간에 요소를 추가하거나 삭제하는 것이 간단하고 빠릅니다.
  4. 다양한 메서드 제공:
    • 배열(Array): 간단한 인덱스 기반 접근 외에도 여러 가지 작업을 수행하는 메서드를 제공하지 않습니다.
    • 리스트(List): 요소를 추가, 제거, 검색하는 등 다양한 작업을 수행하는 메서드를 제공합니다. 예를 들어, Add(), Remove(), Contains() 등의 메서드를 사용할 수 있습니다.
  5. 다차원 구조:
    • 배열(Array): 다차원 배열을 사용하여 행렬 등의 다차원 데이터를 저장할 수 있습니다.
    • 리스트(List): 리스트는 일차원 자료구조이므로 다차원 데이터를 저장하기에는 적합하지 않습니다.

요약하면, 리스트는 크기의 유연성과 요소의 삽입 및 삭제에 효율적이며, 배열은 크기의 고정성과 메모리 관리 측면에서 효율적입니다.


[각각 어느상황에 사용해야 할까?]

  1. 배열(Array)을 사용해야 하는 경우:
    • 고정된 크기의 데이터: 데이터 크기가 변경되지 않고 고정되어 있을 때 사용합니다. 예를 들어, 행렬 연산 등에서 크기가 변하지 않는 데이터 구조를 다룰 때 효과적입니다.
    • 인덱스를 통한 빠른 접근이 필요한 경우: 요소의 인덱스를 사용하여 빠르게 접근해야 할 때 선택합니다. 예를 들어, 성능이 중요한 알고리즘에서 배열을 사용하여 데이터에 빠르게 접근할 수 있습니다.
// 정수형 배열 예시
int[] numbers = new int[5]; // 길이가 5인 정수형 배열 생성

// 배열에 값 할당
numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
numbers[3] = 40;
numbers[4] = 50;

// 배열 순회
for (int i = 0; i < numbers.Length; i++)
{
    Console.WriteLine(numbers[i]);
}
  1. 리스트(List)를 사용해야 하는 경우:
    • 동적인 데이터 크기: 데이터 크기가 동적으로 변하는 경우 사용합니다. 요소의 추가나 제거가 빈번하게 발생할 때 효율적입니다.
    • 요소의 삽입 및 삭제가 필요한 경우: 배열보다 요소의 삽입 및 삭제가 자주 발생하는 상황에서 선택합니다. 데이터의 중간에 요소를 추가하거나 삭제할 때 리스트가 훨씬 효율적입니다.
// 문자열 리스트 예시
List<string> names = new List<string>();

// 리스트에 값 추가
names.Add("Alice");
names.Add("Bob");
names.Add("Charlie");

// 리스트 순회
foreach (string name in names)
{
    Console.WriteLine(name);
}

[마무리 글]

두 자료구조는 공통점이 있는 만큼 사용상황이 헷갈리기도 하지만 특성을 잘 살펴보면 어느 상황에 사용해야 할지 알 수 있습니다. 제가 제시해드린 예시코드를 보시고 어떤 상황에 써야하는지 혼자서 생각해보시고 정리하는 시간을 가지시면 무리없이 알맞은 상황에 사용하실 수 있을 겁니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다