for (int i = 0; i < CLASS_COUNT; ++i) { //안쪽 배열 만들기 classrooms[i] = new string[STUDENT_COUNT_PER_CLASS[i]]; }
int classIndex = 0; //1반 int studentIndex = 0; //첫번째 학생 // 위에서 안쪽 배열을 만들었기 때문에 studentNames는 더이상 null이 아니다. string[] studentNames = classrooms[classIndex]; studentNames[studentIndex] = "Severus";
위의 코드에서 안쪽 배열의 원소에 접근하는 방법은 다음의 2 가지가 있다. 이 2 가지 방법 중에는 방법2가 조금 더 좋다. 특히 for문을 돌리는 것과 같은 조건이 있을 때 더 좋다. 방법2가 deps가 더 얇기 때문이다. 방법1의 경우 바깥 배열의 색인부터 확인한 다음 그 바깥 배열의 안쪽 배열 색인을 찾아서 들어가는 구조이다. 즉 classrooms[0]인지 또는 classrooms[1]인지부터 확인한 후 해당하는 classrooms의 studentName를 찾아야 한다. 방법2의 경우 studentNames를 미리 만들어 두었기 때문에 clarooms의 색인을 찾는 과정을 점프하고 studentNames를 찾으면 된다. 즉 classrooms[0]인지 classrooms[1]인지를 찾는 과정을 점프하여 주어진 classrooms의 색인이 [0]이라면 곧장 classrooms[0]에서 해당하는 studentNames를 찾으면 되는 것이다.
여기서 방법2는 classrooms[0]에 있는 것을 복사해서 studentNames에 넣은 것이라 원본인 classrooms는 바뀌지 않는 것이라 생각될 수 있다. 그러나 바뀐다. 보통 기본자료형은 값에 의한 전달을 한다. new로 만든 것은 기본적으로 그 자체가 참조형 데이터이다. 즉 new로 만든 것은 복사가 아니라 원본이 바뀌는 것이다.
안쪽 배열을 늘릴 수 있는가?
안쪽 배열은 1차원 배열이기 때문에 늘릴 수 없다. 즉 배열의 크기가 2인 배열을 3으로 만들 수는 없다.
1 2 3 4 5
string[][] classrooms = new string[CLASS_COUNT][];
classrooms[0] = new string[3]; classrooms[1] = new string[2]; classrooms[2] = new string[5];
string[][] classrooms = new string[CLASS_COUNT][];
//기존에 있던 크기가 2인 배열인 classrooms의 마지막 인덱스를 가져온다. //학생들 이름을 넣는 코드는 생략 string[] classroom2 = classrooms[1]; //크기가 2인 배열을 3으로 늘린다. string[] newClassroom2 = new string[classroom2.Length + 1];
//for 문을 돌면서 기존의 배열 데이터를 새 배열로 복사한다. 기존 배열의 길이인 2만큼 for문을 돌면서 newClassroom2에 크기 2인 배열의 값을 복사한다. for (int i = 0; i < classroom2.Length; ++i) { newClassroom2[i] = classroom2[i]; }
//classroom의 크기는 2이고, newClassroom2의 크기는 3이기 때문에 for문을 돌았을 때 3번째 배열의 값은 없는 상태이다. (원래 배열의 크기가 2였으므로, 0, 1까지의 값만 복사된 상태이기 때문.)
//마지막 배열에 접근한다. 마지막 배열에 접근할 때 보통 Length -1을 사용한다. //마지막 배열인 2번째 인덱스 배열의 값에 "Leanne"를 넣어준다. newClassroom2[newClassroom2.Length - 1] = "Leanne";
//원래 있던 클래스에 새로 만든 newClassroom2를 넣는다. 이로써 크기가 2인 배열이 3이 되었다. classrooms[1] = newClassroom2;
Array.Copy()를 사용한 복사
1
Array.Copy(원본배열이름, 새 배열(복사할 배열)이름, 원본 배열의 첫 번째 배열부터 복사할 원소의 개수);
1 2 3
string[] sourceArray = classrooms[1]; // classrooms[1];의 원소를 10개로 가정 string[] destinationArray = new string[2]; Array.Copy(sourceArray, destinationArray, destinationArray.Length);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
string[][] classrooms = new string[CLASS_COUNT][];
//학생들 이름을 넣는 코드는 생략 string[] classroom2 = classrooms[1];
string[] newClassroom2 = new string[classroom2.Length + 1];
//Array.Copy(원본배열, 새 배열(복사할 배열), 몇 개만큼 복사할 것인지) //원본배열의 크기는 2, 새 배열의 크기는 3이다. 둘의 크기가 다르기 때문에 //원본배열의 크기인 2만큼 복사하기로 정한다. Array.Copy(classroom2, newClassroom2, classroom2.Length);
//새 배열의 크기는 3이고, 위에서 배열이 2까지일때의 값을 복사했기 때문에 //마지막 배열의 인덱스에 새 값을 넣어준다. newClassroom2[newClassroom2.Length - 1] = "Leanne";
//원래 있던 클래스에 새로 만든 newClassroom2를 넣는다. 이로써 크기가 2인 배열이 3이 되었다. classrooms[1] = newClassroom2;
2D 배열 VS 배열의 배열
2D 배열
배열의 배열
다차원 2D 배열
바깥 배열이 1차원 1D 배열
배열의 각 원소가 배열형이 아니다.
행을 나타내는 바깥 배열의 각 원소도 1D 배열이다.
엑셀 형태
바깥 배열인 1차원 배열(행) 안에 안쪽배열인 1차원 배열(열)이 존재
비어 있는 원소가 있을 수 있다.
필요한 만큼 안쪽 배열읠 길이를 잡을 수 있다.
참고로 안쪽 배열에 1D 배열이 아닌 2D 배열을 원소로 가질 수 있긴 하지만 잘 쓰이진 않는다.