C#프로그래밍 12 : 배열 (선언, 초기화), System.Array/Index/Range, 가변배열

LeeWonjin·2022년 5월 6일
0

[학부]C#프로그래밍

목록 보기
12/21

일반적인 사실

배열은 참조형식이다. (배열의 참조는 스택에, 원소들의 값은 힙에 할당됨)
데이터형식[] 배열이름 = new 데이터형식[크기];
string[] names = new string[53];

1차원 배열 선언 및 초기화

아래 세 문장은 같은 결과를 낸다.

public static void Main(string[] args)
{
    int[] a = new int[5] { 0, 1, 2, 3, 4 };
    int[] b = new int[] { 0, 1, 2, 3, 4 };
    int[] c = { 0, 1, 2, 3, 4 };

    int[][] container = { a, b, c };
    foreach(int[] arr in container)
    {
        foreach(int el in arr)
        {
            Console.Write($"{el} "); // 0 1 2 3 4
        }
        Console.WriteLine();
    }
}

다차원 배열 선언 및 초기화

아래와 같이 n차원 배열을 선언, 생성할 수 있다.
int[,,, ... ,,,] arr = new int[n차원 크기, n-1차원 크기, ..., 1차원 크기]
int[,,, ... ,,,]에서 콤마(,)는 n-1개이다.

2차원 배열로 예를 들면, 아래 int[,] arr1~arr3 세 문장은 같은 결과를 낸다.

private static void print(int[,] arr)
{
    for(int i=0; i<arr.GetLength(0); i++)
    {
        for(int j=0; j<arr.GetLength(1); j++)
        {
            Console.Write($"{arr[i, j]} ");
        }
        Console.Write(" / ");
    }
    Console.WriteLine();
}

public static void Main(string[] args)
{
    int[,] arr1 = new int[2, 3] { { 1, 2, 3 }, { 4, 5, 6 } };
    int[,] arr2 = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } };
    int[,] arr3 = { { 1,2,3 }, { 4, 5, 6 } };

    print(arr1); // 1 2 3  / 4 5 6  /
    print(arr2);
    print(arr3);
}

Index from end (^) 연산자

caret연산자라고도 부름. 배열의 마지막 인덱스부터 역순으로 지정
^1 --> 마지막 인덱스 (arr.length - 1)
^2 --> 뒤에서 두 번째 인덱스 (arr.length - 2)

public static void Main(string[] args)
{
    int[] arr = new int[5] { 0, 1, 2, 3, 4 };
            
    for(int i=0; i<arr.Length; i++)
    {
        Console.Write($"{arr[i]}"); //01234
    }

    Console.WriteLine();

    for (int i = 1; i <= arr.Length; i++)
    {
        Console.Write($"{arr[^i]}"); // 43210
    }
}

System.Array

C#의 배열은 .NET CTS의 System.Array 클래스에 대응됨
코드에서 using System을 사용하고 있다면, Array로 접근 가능

static 메소드

<T>가 붙어있는 메소드의 경우 대리자를 사용한다.
대리자는 함수를 매개변수로 넘겨주기 위해 사용한다.

  • Sort() : 정렬
int[] arr = new int[5] { 20,30,40,10,0 };
Array.Sort(arr);
foreach(int el in arr) { Console.Write($"{el} "); }
// 0 10 20 30 40
  • BinarySearch() : 이진탐색
int[] arr = new int[5] { 10,20,30,40,50 };
int idx = Array.BinarySearch<int>(arr, 50);
Console.WriteLine(idx); // 4 (index of 50)
  • IndexOf() : 특정 데이터의 인덱스 반환
int[] arr = new int[5] { 10,20,30,40,50 };
int idx = Array.IndexOf<int>(arr, 10);
Console.WriteLine(idx); // 0
  • TrueForAll() : 배열의 모든 요소가 조건에 부합하는지 여부 반환
int[] arr = new int[5] { 10,20,30,40,50 };
bool result = Array.TrueForAll<int>(arr, new Predicate<int>((int num) => num < 100));
Console.WriteLine(result); // True
  • FindIndex() : 조건에 맞는 첫 요소 인덱스 반환
private static bool isPassed(int n)
{
    return n > 30;
}
public static void Main(string[] args)
{
    int[] arr = new int[5] { 10,20,30,40,50 };
    int result = Array.FindIndex<int>(arr, new Predicate<int>(isPassed));
    Console.WriteLine(arr[result]); // 40 (result는 3)
}
  • Resize() : 크기 재조정
public static void Main(string[] args)
{
    int[] arr = new int[5] { 10,20,30,40,50 };
    Array.Resize<int>(ref arr, 15);
    Array.ForEach<int>(arr, new Action<int>( (int n)=>Console.Write($"{n} ")) );
    // 10 20 30 40 50 0 0 0 0 0 0 0 0 0 0
}
  • Clear() : 모든요소 초기화
public static void Main(string[] args)
{
    int[] arr = new int[5] { 10,20,30,40,50 };
    Array.Clear(arr);
    foreach(int n in arr) { Console.Write("{0} ", n); } // 0 0 0 0 0
}
  • ForEach()
static void sqr(int n)
{
    Console.Write($"{n * n} ");
}
public static void Main(string[] args)
{
    int[] arr = new int[5] { 20,30,40,10,0 };
    Array.ForEach<int>(arr, new Action<int>(sqr));
    // 400 900 1600 100 0
}
  • Copy() : 배열의 일부를 다른 배열에 복사
public static void Main(string[] args)
{
    int[] src = new int[5] { 10,20,30,40,50 };
    int[] dest = new int[3];

    Array.Copy(src, 2, dest, 0, dest.Length);
    foreach (int n in dest) { Console.Write($"{n} "); } // 30 40 50
}

인스턴스 메소드

  • GetLength() : 지정한 차원의 길이 반환

프로퍼티

  • Length : 길이
  • Rank : 차원
int[] arr = new int[5] { 10,20,30,40,50 };
Console.WriteLine(arr.Rank); // 1

System.Index (인덱스)

인덱스를 나타내는 형식이다.

int[] arr = new int[5] { 10,20,30,40,50 };

System.Index last = ^1;
Console.WriteLine(arr[last]); // 50

System.Range (배열 분할)

System.Range형식으로 범위 표현 (Array.Copy()의 대안이 될 수있음)
아래 세 가지 방법은 같은 결과를 낸다.

private static void print(int[] arr)
{
    foreach (int i in arr) { Console.Write($"{i} "); }
    Console.WriteLine();
}
public static void Main(string[] args)
{
    int[] src = new int[5] { 10,20,30,40,50 };

    // 1
    System.Range range1 = new System.Range(0, 2);
    print(src[range1]); // 10 20
            
    // 2
    System.Range range2 = 0..2;
    print(src[range2]); // 10 20

    // 3
    print(src[0..2]); // 10 20
}

그 외의 예제는 아래와 같다.

private static void print(int[] arr)
{
    foreach (int i in arr) { Console.Write($"{i} "); }
    Console.WriteLine();
}
public static void Main(string[] args)
{
    int[] src = new int[5] { 10,20,30,40,50 };

    print(src[1..]); // 20 30 40 50
    print(src[..2]); // 10 20
    print(src[^4..^1]); // 20 30 40

    System.Index first = ^5;
    print(src[first..5]); // 10 20 30 40 50
    print(src[..]); // 10 20 30 40 50
}

가변배열

다른 길이의 배열을 요소로 가질 수 있는 다차원 배열

public static void Main(string[] args)
{
    int[][] arr = new int[3][];
    arr[0] = new int[5] {1,2,3,4,5};
    arr[1] = new int[] {1,2,3};
    arr[2] = new int[10];
        
    for(int i=0; i<arr.Length; i++)
    {
        for(int j=0; j<arr[i].Length; j++)
        {
            Console.Write($"{arr[i][j]} ");
            /*
                1 2 3 4 5
            1 2 3
            0 0 0 0 0 0 0 0 0 0
                */
        }
        Console.WriteLine();
    }
}
profile
노는게 제일 좋습니다.

0개의 댓글