C#에서 배열을 사용하는 방법에 대해 알아보도록 합시다. 가장 기초적인 1차원 배열을 알아본 다음, 2차원 및 3차원과 같은 다차원 배열, 그리고 마지막으로 가변 배열에 대해 알아보도록 해요.
배열 (1차원 배열)
단순히 '배열'이라고 지칭하면 당연히 1차원 배열을 의미할 것입니다. '1차원'은 당연히 보통 생략하여 표현해요. int 데이터타입을 기준으로 안내해 드릴게요.
//배열(1차원)
int[] array1 = new int[5];
int[] array2 = { 10, 20, 30, 40, 50, 60 };
int[] array3 = new int[] { 1, 2, 3, 4, 5, 6 };
int[] array4 = new int[6] { 1, 2, 3, 4, 5, 6 };
array1[0] = 1;//할당
배열은 선언과 할당이 있는데요, int[] array 와 같이 선언하며, 선언과 동시에 값을 할당할 때에는 new int[3], {1, 2, 3}, new int[3] {1, 2, 3}, new int[] {1, 2, 3} 과 같이 다양한 방법으로 할 수 있어요. 길이를 명시적으로 지정할 때에는 할당한 배열과 같은 길이의 배열 이니셜라이저를 설정하세요.
배열 이니셜라이저 길이 오류
//CS0847 길이가 '5'인 배열 이니셜라이저가 필요합니다
int[] array0 = new int[5] { 1, 2, 3, 4, 5, 6 };
정상적으로 처리한 예시
int[] array0 = new int[5] { 1, 2, 3, 4, 5 };
for 반복문으로 각 배열 요소에 접근하는 방법은 다음과 같아요. 배열의 길이, Length를 이용하세요.
int[] array = { 10, 20, 30, 40, 50, 60 };
Debug.WriteLine("배열");
for (int i = 0; i < array.Length; i++)
{
Debug.WriteLine($"(i) => ({i}) => {array[i]}");
}
//출력
배열
(i) => (0) => 10
(i) => (1) => 20
(i) => (2) => 30
(i) => (3) => 40
(i) => (4) => 50
(i) => (5) => 60
2차원 배열 (다차원 배열)
2차원 배열의 선언은 int[,]와 같이 합니다.
int[,] array2D_1 = new int[2, 3];
int[,] array2D_2 = { { 1, 2, 3 }, { 4, 5, 6 } };
int[,] array2D_3 = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } };
int[,] array2D_4 = new int[2, 3] { { 1, 2, 3 }, { 4, 5, 6 } };
그리고 위에서 볼 수 있듯이, 2차원 배열은 1차원 배열을 다시 배열한 것이에요. 응용하면, 나중에 나올 3차원 배열은 2차원 배열을 다시 배열한 것이랍니다. 참고로 1차원 배열은 0차원 요소의 집합이라고 볼 수 있어요.
2차원 배열은 1차원 배열의 집합이고요, 각 1차원 배열은 0차원 요소를 가지고 있습니다. 각 요소는 Array.GetLength 메서드로 접근할 수 있어요. 다음의 예시를 참고해 주세요.
int[,] array2D = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } };
Debug.WriteLine("2차원 배열");
for (int i0 = 0; i0 < array2D.GetLength(0); i0++)
{
Debug.WriteLine($"(i0) => ({i0}) => {i0}");
for (int i1 = 0; i1 < array2D.GetLength(1); i1++)
{
Debug.WriteLine($"(i0, i1) => ({i0}, {i1}) => {array2D[i0, i1]}");
}
}
//출력
2차원 배열
(i0) => (0) => 0
(i0, i1) => (0, 0) => 1
(i0, i1) => (0, 1) => 2
(i0, i1) => (0, 2) => 3
(i0) => (1) => 1
(i0, i1) => (1, 0) => 4
(i0, i1) => (1, 1) => 5
(i0, i1) => (1, 2) => 6
1차원 배열은 크게 어렵지 않아서 오류가 거의 발생하지 않을 텐데, 다차원 배열부터는 헷갈리는 면이 있지요. 오류를 몇 개 모아보았어요.
//인덱스가 배열 범위를 벗어났습니다.
int getLength2 = array2D.GetLength(2);
//CS0847 길이가 'x'인 배열 이니셜라이저가 필요합니다
array2D = new int[,] { { 1, 2, 3 }, { 4, 5, 6, 7 } };
//CS0022 [] 내부의 인덱스 수가 잘못되었습니다. 2개가 필요합니다.
array2D[0] = 1;
//CS0029 암시적으로 'int[]' 형식을 'int' 형식으로 변환할 수 없습니다.
array2D[0, 0] = new int[] { 1, 1 };
//CS0846 중첩 배열 이니셜라이저가 필요합니다.
array2D = new int[,] { new int[] { 1, 2, 3 }, { 4, 5, 6 } };
//CS1586 배열을 만들 때에는 배열 크기 또는 배열 이니셜라이저가 있어야 합니다.
array2D = new int[];
인덱스가 배열 범위를 벗어났습니다. => n차원 배열의 GetLength는 (n-2)와 (n-1)이 있습니다. 즉, 2차원은 GetLength(0)과 GetLength(1)이 있기에 GetLength(2)는 인덱스 배열 범위 밖이에요.
CS0022 [] 내부의 인덱스 수가 잘못되었습니다. 2개가 필요합니다. => 2차원 배열의 값을 할당할 때에는 array2D[0, 0] = 1; 과 같이 할 수 있어요.
CS0029 암시적으로 'int[]' 형식을 'int' 형식으로 변환할 수 없습니다. => 2차원 배열의 값을 할당할 때에는 array2D[0, 0] = 1; 과 같이 할 수 있어요.
CS0846 중첩 배열 이니셜라이저가 필요합니다. => 배열의 할당은 array2D = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } }; array2D = new int[2, 3] { { 1, 2, 3 }, { 4, 5, 6 } }; 과 같이 해요.
CS1586 배열을 만들 때에는 배열 크기 또는 배열 이니셜라이저가 있어야 합니다. => 배열의 할당 부분을 다시 확인해 주세요.
3차원 배열 (다차원 배열)
2차원 배열까지는 가끔 사용하는데, 3차원 배열은 보기 힘든 것 같군요.
3차원 배열은 2차원 배열의 집합을 확인할 수 있어요.
int[,,] array3D_1 = new int[1, 2, 3];
int[,,] array3D_2 = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, { { 7, 8, 9 }, { 10, 11, 12 } } };
int[,,] array3D = {
{ { 1, 2, 3 }, { 4, 5, 6 } },
{ { 10, 20, 30 }, { 40, 50, 60 } },
{ { 7, 8, 9 }, { 10, 11, 12 } },
{ { 70, 80, 90 }, { 100, 110, 120 } }
};
3차원 배열 또한 2차원 배열과 마찬가지로 GetLength로 차원의 길이를 확인할 수 있습니다.
Debug.WriteLine("3차원 배열");
for (int i0 = 0; i0 < array3D.GetLength(0); i0++)
{
Debug.WriteLine($"(i0) => ({i0}) => {i0}");
for (int i1 = 0; i1 < array3D.GetLength(1); i1++)
{
Debug.WriteLine($"(i1) => ({i1}) => {i1}");
for (int i2 = 0; i2 < array3D.GetLength(2); i2++)
{
Debug.WriteLine($"(i0, i1, i2) => ({i0}, {i1}, {i2}) => {array3D[i0, i1, i2]}");
}
}
}
//출력
3차원 배열
(i0) => (0) => 0
(i1) => (0) => 0
(i0, i1, i2) => (0, 0, 0) => 1
(i0, i1, i2) => (0, 0, 1) => 2
(i0, i1, i2) => (0, 0, 2) => 3
(i1) => (1) => 1
(i0, i1, i2) => (0, 1, 0) => 4
(i0, i1, i2) => (0, 1, 1) => 5
(i0, i1, i2) => (0, 1, 2) => 6
(i0) => (1) => 1
(i1) => (0) => 0
(i0, i1, i2) => (1, 0, 0) => 10
(i0, i1, i2) => (1, 0, 1) => 20
(i0, i1, i2) => (1, 0, 2) => 30
(i1) => (1) => 1
(i0, i1, i2) => (1, 1, 0) => 40
(i0, i1, i2) => (1, 1, 1) => 50
(i0, i1, i2) => (1, 1, 2) => 60
(i0) => (2) => 2
(i1) => (0) => 0
(i0, i1, i2) => (2, 0, 0) => 7
(i0, i1, i2) => (2, 0, 1) => 8
(i0, i1, i2) => (2, 0, 2) => 9
(i1) => (1) => 1
(i0, i1, i2) => (2, 1, 0) => 10
(i0, i1, i2) => (2, 1, 1) => 11
(i0, i1, i2) => (2, 1, 2) => 12
(i0) => (3) => 3
(i1) => (0) => 0
(i0, i1, i2) => (3, 0, 0) => 70
(i0, i1, i2) => (3, 0, 1) => 80
(i0, i1, i2) => (3, 0, 2) => 90
(i1) => (1) => 1
(i0, i1, i2) => (3, 1, 0) => 100
(i0, i1, i2) => (3, 1, 1) => 110
(i0, i1, i2) => (3, 1, 2) => 120
4차원 배열
3차원 배열까지 보며, 어느 정도 감이 잡히시죠? 콤마의 개수는 3개랍니다. (n-1개)
int[,,,] array4D = new int[1, 2, 3, 4];
가변 배열
'가변 배열'은 각 배열 요소마다 길이를 달리 할 수 있는 배열을 뜻하며, 가장 기본적인 선언과 할당은 int[][] jaggedArray = new int[4][]; 처럼 합니다. 대괄호가 하나 더 있어요~
가변 배열을 할당하는 예시를 살펴보겠습니다. (선언과 할당은 위에서 많이 했으니 생략할게요)
가변 배열은 길이 또는 배열 이니셜라이저가 있어야 하기에 첫 번째 브래킷에서 길이를 확인할 수 있어요.
int[][] jaggedArray = new int[4][];
jaggedArray[0] = new int[] { 0, 1, 2, 3 };
jaggedArray[1] = new int[] { 10, 20 };
jaggedArray[2] = new int[] { 100, 200, 300 };
jaggedArray[3] = new int[] { 1004 };
배열 길이는 Length와 array[i].Length 입니다. 출력 예시는 다음과 같습니다.
Debug.WriteLine("가변 배열");
for (int i = 0; i < jaggedArray.Length; i++)
{
Debug.WriteLine($"i => ({i}) => {i}");
for (int j = 0; j < jaggedArray[i].Length; j++)
{
Debug.WriteLine($"(i, j) => ({i}, {j}) => {jaggedArray[i][j]}");
}
}
//출력
가변 배열
i => (0) => 0
(i, j) => (0, 0) => 0
(i, j) => (0, 1) => 1
(i, j) => (0, 2) => 2
(i, j) => (0, 3) => 3
i => (1) => 1
(i, j) => (1, 0) => 10
(i, j) => (1, 1) => 20
i => (2) => 2
(i, j) => (2, 0) => 100
(i, j) => (2, 1) => 200
(i, j) => (2, 2) => 300
i => (3) => 3
(i, j) => (3, 0) => 1004
가변 다차원 배열 (2차원 예시)
가변 배열도 다차원으로 할당할 수 있어요. 이렇게 사용하는 사람은 본 적이 없기는 한데, 이러한 방법도 있다는 것 정도만 알면 될 것 같아요.
//가변배열 2차원
int[][,] jagged2DArray = new int[2][,];
jagged2DArray[0] = new int[,] { { 1, 2, 3, 4 }, { 11, 12, 13, 14 }, { 21, 22, 23, 24 } };
jagged2DArray[1] = new int[,] { { 1 }, { 2 } };
가변 배열 2차원 예시 출력입니다.
Debug.WriteLine("2차원 가변 배열");
for (int i = 0; i < jagged2DArray.Length; i++)
{
for (int i0 = 0; i0 < jagged2DArray[i].GetLength(0); i0++)
{
Debug.WriteLine($"(i, i0) => ({i}, {i0})");
for (int i1 = 0; i1 < jagged2DArray[i].GetLength(1); i1++)
{
Debug.WriteLine($"(i, i0, i1) => {jagged2DArray[i][i0, i1]}");
}
}
}
//출력
2차원 가변 배열
(i, i0) => (0, 0)
(i, i0, i1) => 1
(i, i0, i1) => 2
(i, i0, i1) => 3
(i, i0, i1) => 4
(i, i0) => (0, 1)
(i, i0, i1) => 11
(i, i0, i1) => 12
(i, i0, i1) => 13
(i, i0, i1) => 14
(i, i0) => (0, 2)
(i, i0, i1) => 21
(i, i0, i1) => 22
(i, i0, i1) => 23
(i, i0, i1) => 24
(i, i0) => (1, 0)
(i, i0, i1) => 1
(i, i0) => (1, 1)
(i, i0, i1) => 2
