5.1.7 2차원 정방 행렬 배열 - 1

jh·2022년 1월 23일
0

Do it! 자바 완전 정복

목록 보기
38/70

가로 및 세로 방향의 2차원으로 데이터를 저장하는 배열이 2차원 배열이다. 그중 직사각형의 형태(모든 행의 길이가 같은 배열)를 띤 배열을 '2차원 정방 행렬 배열'이라고 한다.

2차원 배열을 선언할 때도 배열을 대괄호([])로 표시한다. 다만 1차원 배열과 다른 점은 2차원이라는 것을 나타내기 위해 2개의 대괄호로 표시한다는 것이다.

🍃2차원 배열의 선언 방법
자료형[][] 변수명 | 자료형 변수명[][] | 자료형[] 변수명[]

int[][] a;     | int a[][];      | int[] a[];
double[][] b;  | double b[][];   | double[] b[];
String[][] c;  | String c[][];   | String[] c[];

2차원 배열의 선언을 보면 차원이 1개씩 늘어날 대마다 대괄호가 1개씩 늘어난다는 것을 알 수 있다. 따라서 3차원 이상의 배열을 선언하는 방법도 쉽게 유추할 수 있을 것이다. 대괄호 안에는 배열의 인덱스가 들어가는데, 2차원 배열은 각 위치 정보가 2개의 인덱스 쌍으로 이뤄져 있다. 배열의 위치 표현은 세로 방향으로 숫자가 늘어나는 행row 번호와 가로 방향으로 숫자가 늘어나는 열 column 번호로 구성돼 있으며 각 방향의 인덱스는 0부터 시작한다. 예를 들어 a[2][1]은 2차원 배열 a의 세번째 행과 두 번째 열을 의미한다.

실습

        int[] array = new int[] {3, 4, 5, 6, 7};
        
        // 배열의 선언 방법 1 - 자료형 뒤에 대괄호 2개 표기
        int [][] array1 = new int [3][4];
        int [][] array2;
        array2 = new int[3][4];
        
        // 배열의 선언 방법 2 - 변수명 뒤에 대괄호 2개 표기 
        int array3[][] = new int[3][4];
        int array4[][];
        array4 = new int [3][4];
        
        // 배열의 선언 방법 3 - 자료형과 변수명 뒤에 각각 하나의 대괄호 표기 
        int[] array5[] = new int[3][4];
        int[] array6[];
        array6 = new int[3][4];
        
        // 다양한 배열 선언 ( 기본 자료형 배열, 참조 자료형 배열)
        boolean[][] array7 = new boolean[3][4];
        int[][] array8 = new int[2][4];
        double[][] array9 = new double[3][5];
        String[][]array10 = new String[2][6]; // 참조 자료형 배열 

2차원 정방 행렬은 객체를 생성하는 데도 4가지 방법이 있다. 각 방법을 이해하는 것보다 더욱 중요한 사실은 '메모리는 2차원 데이터를 바로 저장할 수 없다.'는 것이다. 지금까지 2차원 배열을 공부해놓고 메모리에 2차원을 저장할 수 없다고 하니 이해하기 힘들 것이다. 실제로 메모리는 1차원 형태의 데이터만 저장할 수 있다.
그렇다면 어떻게 2차원 데이터를 저장할까? 그 방법은 2차원 데이터를 1차원 데이터들로 나눠 저장하는 것이다. 다음과 같은 2X3 크기의 2차원 배열을 살펴 보자.

이 배열의 각 행은 1차원 배열이다. 배열의 첫 번째 특징은 동일한 자료형만 묶어 저장할 수 있다는 것이었다. 즉, 각각의 행이 1차원 배열이므로 '2차원 배열은 1차원 배열을 원소로 포함하고 있는 1차원 배열'이라고 생각할 수 있다. 이 개념을 3차원 배열로 확장하면 3차원은 2차원 배열의 객체를 생성하는 방법과 메모리에서의 동작을 이해할 수 있다.
이제 2차원 정방행렬 배열의 4가지 객체 생성 방법을 알아보자.

방법 ① 배열 객체를 생성하고 값 대입하기
첫 번째 방법은 2차원 배열 객체를 선언한 후 각각의 인덱스 위치에 값을 하나씩 대입하는 것이다. 여기서도 배열의 2가지 특징을 모두 만족한다는 것을 알 수 있다. 우선 어떤 자료형을 저장하는지가 선언에 나와 있고 객체를 생성할 때 배열의 길이가 지정돼 있다.

🍊2차원 정방 행렬 배열 객체를 생성하고 값 대입하기
자료형[][] 참조 변수명 = new 자료형 [행의 길이][열의 길이];
참조 변수명[0][0] = 값;
참조 변수명[0][1] = 값;
...
참조 변수명 [행의 길이 -1][열의 길이-1] = 값;

int[][]a = new int[2][3];
a[0][0] = 1; a[0][1] = 2; a[0][2] = 3;
a[1][0] = 4; a[1][1] = 5; a[1][2] = 6;

여기서 중요한 점은 메모리를 이해한다는 것이다. 위 예제에서 2차원 배열은 길이가 3인 1차원 배열을 2개 포함하고 있는 1차원 배열로 볼 수 있다. 즉 int[]가 int를 저장하는 1차원 배열인 것 처럼 int[][]는 int[]를 저장하는 1차원 배열로 볼 수 있다는 말이다. 따라서 몇 차원의 배열이든 최종적으로는 1차원 배열로 분할할 수 있으며 이것이 바로 1차원 데이터만 저장할 수 있는 메모리에 다차원 배열을 저장할 수 있는 이유다.
이제 다시 메모리의 구조로 돌아가 다음 예제를 이용해 생성되는 메모리의 구조를 살펴 보자.

2차원 배열의 참조 변수 a는 2개의 원소(1차원 배열)를 포함하고 있는 1차원 배열 이므로 참조 변수가 가리키는 곳으로 가면 2개의 방이 있다. 이 2개의 방에는 서로 다른 2차원 배열의 위칫값이 들어 있다. 이 위칫값들이 가리키는 또 다른 힙 메모리의 공간에 객체의 실제 데이터 값이 들어 있다. 다소 복잡해 보이지만, 앞의 예제에서 메모리 구조를 자세히 살펴보면 이해할 수 있을 것이다.

메모리의 저장 구조를 이해해야 2차원 배열의 length 속성값을 알 수 있다. '배열 참조 변수.length'는 배열의 길이를 나타낸다고 했다. 다시 말해서 배열의 가리키는 곳으로 가서 방의 개수를 알아오는 것이 '배열 참조 변수.length'의 명령어다. 그렇다면 앞의 예제에서 a.length는 얼마인가? 참조 변수 a가 가리키는 곳으로 가면 2칸의 공간이 있다. 즉 a.length = 2인 것이다. 반면 a[0].length는 a가 가리키는 곳의 방 개수를 의미하므로 a[0].length = 3이 된다. 이와 같은 방식으로 a[1].length = 3이 된다는 것을 알 수 있다.

🍊2차원 배열의 길이 가져오기

System.out.println(a.length); //2
System.out.println(a[0].length); //3
System.out.println(a[1].length); //3
profile
코딩 공부 중...

0개의 댓글