PRIVATE/Java

6장 - 여러 값 한 번에 저장하기: 배열

sonotree 2025. 3. 5. 13:46

지금까지 변수를 선언하면 숫자, 문자, 문자열 등 값을 하나씩 저장했다. 이번에는 값이 여러 개일 때 이를 변수 하나로 묶어 한 번에 저장하는 배열에 대해 알아보자.

 

 

6.1. 배열의 기본

6.1.1. 배열이란 ★

변수어떤 자료형의 값을 저장하기 위한 공간이다. 배열은 이런 변수가 여러 개 연속해 있다고 보면 된다. 즉, 배열(array)같은 자료형의 값 여러 개를 변수 하나로 묶어 관리하는 것이다.

 

배열을 사용하면 학생 4명의 점수를 각각의 변수에 저장하지 않고, 아래와 같이 바꿀 수 있다.

int [] scroeArray = {80, 90, 100, 70};

 

배열을 사용하니 4줄로 작성되었던 코드가 1줄로 줄고, 변수 1개로 값 4개를 관리할 수 있다. 예제는 변수가 4개라서 간단해보이지만 값이 수천 수만개라고 생각하면 배열이 얼마나 효율적인지 알 수 있다.
-> 배열은 같은 유형의 데이터를 효율적으로 관리하기 위해 필요하다.

 

배열과 변수의 구조를 비교하면 다음과 같다. 같은 자료형(여기서는 int)의 값들을 하나의 변수에 묶어 관리한다.

 

 

 

6.1.2. 배열 선언하기

변수와 마찬가지로, 배열을 사용하려면 먼저 선언해야 한다. 배열을 선언하는 방법 또한 변수를 선언하는 방법과 비슷하다. 

-> 변수 선언과 방법은 동일한데, 배열임을 알려주기 위해 []를 붙인다.....!라고 외우면 편함

자료형 [] 배열명;
// int [] scoreArray;

자료형 배열명 [];
// int scoreArray [];

 

 

 

6.1.3. 배열 초기화하기: 2가지 방식 ★

선언만 해서는 배열을 사용할 수 없다. 배열을 초기화해야한다. 배열을 초기화하는 방법은 크게 두 가지로 나뉜다. 첫 번째는 내가 알고있는 방식이다. (1) 선언과 동시에 값을 넣어 초기화하는 방식!

자료형 [] 배열명 = {값1, 값2, ...};
// int [] scoreArray = {90, 80, 100};

-> 배열을 선언하고 대입 연산자 = 로 값을 넣어 초기화한다. 

-> 이렇게 작성하면 초깃값의 개수에 따라 배열 크기가 자동으로 결정된다.

-> 이때 배열 안에 담긴 값들의 자료형은 모두 같아야한다. 즉, 정수형 배열을 선언하면 선언한 값도 모두 정수여야 하고 String으로 배열을 선언하면 값도 모두 문자열이여야 한다.

 

 

두 번째는 (2) 크기를 지정해 배열을 생성하는 방법이다! 이 방법은 new라는 키워드를 사용한다. new 키워드 뒤에 자료형이 오고 대괄호 안에 배열 크기를 명시한다. 배열 크기는 배열에 저장할 수 있는 값의 최대 개수를 나타낸다.

자료형 [] 배열명 = new 자료형[배열_크기];
// int [] scoreArray = new int[4];

-> 크기를 지정해 배열을 선언하고 나면, 자료형의 기본값으로 초기화되며, 자료형별 기본값은 다음과 같다.

  • 정수형: 0
  • 실수형: 0.0
  • 문자형: \u0000(null 문자)
  • 논리형: fasle
  • 문자열: null

아래와 같이 작성하면 int형의 scoreArray라는 이름의 크기가 4인 배열을 선언하고, 값을 모두 0으로 초기화한다.

int [] scoreArray = new int[4];

 

 

 

6.1.4. 배열에 접근하기 ★

배열에 저장된 값을 배열의 요소(element)라고 한다. 

변수는 변수 당 값이 하나뿐이어서 변수명만으로 값에 접근할 수 있지만, 배열은 요소가 여러개이다. 따라서 변수명만으로는 원하는 요소에 접근할 수 없다. -> 그래서 배열에서는 요소의 위치를 나타내는 인덱스(index)를 사용한다. 인덱스는 아래와 같이 대괄호 안에 넣어 표시한다.

 

scoreArray 배열의 각 요소에 접근할 떄는 인덱스를 다음과 같이 사용한다.

public class Main {
    public static void main(String[] args) {
        int [] scoreArray = {100, 90, 80, 70};
        System.out.println("1번 학생의 점수=" + scoreArray[0]);
        System.out.println("2번 학생의 점수=" + scoreArray[1]);
        System.out.println("3번 학생의 점수=" + scoreArray[2]);
        System.out.println("4번 학생의 점수=" + scoreArray[3]);
    }
}

이처럼 배열에서는 인덱스로 배열의 값에 접근할 수 있다.

 

 

 

6.1.5. 배열의 값을 변경하기

시험 결과가 잘못 채점되서 학생들의 점수를 각각 0, 10, 20, 30점으로 조정한다고 하자. 즉, scoreArray 배열의 값을 모두 바꿔야 한다. 이때는 해당 위치에 접근한 후 새로운 값을 저장하면 된다.

배열명[인덱스] = 새로운_값;
// scoreArray[1] = 10;

-> scoreArray[1]이므로 scoreArray 배열의 인덱스 1에 접근해 값을 10으로 변경한다. 그러면 2번 학생의 점수가 90점에서 10점으로 바뀐다.

 

 

 

6.1.6. 배열에서 반복문 사용하기

앞의 코드를 보면 출력문에서 숫자만 바뀌고 비슷한 코드가 반복된다. 다시 말해, 반복문을 사용할 수 있다는 의미이다.

먼저 코드에서 반복되는 부분과 아닌 부분을 찾아야 한다. 두 부분이 있고 각각 인덱스가 1씩 증가한다.

 

코드로 작성하면 아래와 같다.

public class Main {
    public static void main(String[] args) {
        int [] scoreArray = {100, 90, 80, 70};
        for (int i=0; i<=3; i++){
            System.out.printf("%d번 학생의 점수 = %d\n", (i+1), scoreArray[i]);
        }
    }
}

 

 

 

 

6.1.7. 배열의 크기: length 속성

배열 크기를 이용해 범위를 지정할 수도 있다. 배열 크기는 length 속성으로 알 수 있고, "배열명.length" 형태로 사용한다.

배열의 크기는 배열에 저장된 값의 개수가 아니라, 저장할 수 있는 최대 개수임을 알 수 있다.

 

앞에서 작성한 for문의 조건식을 아래와 같이 바꿔도 실행 결과는 동일하다.

public class Main {
    public static void main(String[] args) {
        int [] scoreArray = {100, 90, 80, 70};
        for (int i=0; i<scoreArray.length; i++){
            System.out.printf("%d번 학생의 점수 = %d\n", (i+1), scoreArray[i]);
        }
    }
}

 

참고로 배열의 크기는, 배열에 저장된 값의 개수가 아니라 저장할 수 있는 최대 개수이다.

public class Main {
    public static void main(String[] args) {
        int [] scoreArray = new int[5];
        scoreArray[0] = 10;
        scoreArray[1] = 20;
        scoreArray[2] = 30;
        scoreArray[3] = 40;

        System.out.println("배열 크기: " + scoreArray.length);
        System.out.println(Arrays.toString(scoreArray));

    }
}

 

 

 

6.1.8. QUIZ

다음 코드를 실행할 때 어떤 결과가 나올지 작성하라

public class Main {
    public static void main(String[] args) {
        int [] numbers = new int[4];
        int value = 10;
        for(int i=0; i<numbers.length; i++){
            numbers[i] = value * (i+1);
        }
        for (int i=0; i<numbers.length; i++){
            System.out.println("numbers[" + i + "]=" + numbers[i]);
        }
    }
}

 

내 답변) - 정답

numbers.length = 4 따라서

"numbers[0]=10

numbers[1]=20

numbers[2]=30

numbers[3]=40"

조건문이나 반복문이 여러개 있다고 출력값이 여러개 인 것은 아님
출력 스트림이 있는 부분만 출력됨

6.2. 이차원 배열

1차원 배열이 여러 개 모이면 이차원 배열을 구성한다. 이차원 배열배열 안에 배열이 존재하는 형태이다.

이차원 배열을 행(row)와 열(columm)로 구성된다.

 

6.2.1. 이차원 배열 선언하기

이차원 배열을 선언할 때는 대괄호 2개([][])를 사용한다.

 

 

 

6.2.2. 이차원 배열 초기화하기 ★★

초기화하는 방법은 일차원 배열과 마찬가지로 2가지가 있다.첫 번째는 (1) 배열을 선언할 때 직접 값을 넣어 초기화하는 방법이다. 이차원 배열 안에 일차원 배열이 값으로 들어 있는 형태이다. 각 일차원 배열은 쉼표로 구분한다.

자료형 [][] 배열명 = {{값1, 값2}, {값1, 값2}, ...};
int [][] array = {{1,2,3,4}, {1,2,3,4,}, {1,2,3,4}};
/*이 경우에는 행과 열의 크기를 지정하지 않았지만 3x4로 값이 초기화되었기 때문에 Java가 자동으로
배열의 크기를 3x4로 정해준다*/

 

 

두 번째는 (2) 배열 크기로 생성하는 방법이다. new 키워드를 사용하고 자료형 뒤에 행과 열의 크기를 각각 명시한다.

자료형 [][] 배열명 = new 자료형 [행 크기][열 크기]
//int [][] array2 = new int [3][3];
Java에서 이차원 배열을 선언할 때 [][] 안의 숫자를 생략하는 경우가 있다.
1. 배열만 선언하는 경우
int [][] array;
-> 크기를 지정하지 않고 배열만 선언한 상태이다.

2. 일부 크기만 지정하는 경우
int [][] array = new int [3][ ]; -> 행의 크기만 정해놓은 상태
array[0] = new int [2]; -> 1행의 열 크기를 2로 지정
array[1] = new int [3]; -> 2행의 열 크기를 3으로 지정
array[2] = new int [5]; -> 3행의 열 크기를 5로 지정

3. 크기를 완정히 지정하는 경우
int [][] array = new int [3][4];
-> 이 경우에는 모든 요소가 0으로 초기화된다.

4. 크기 없이 선언 + 동시에 초기화
int [][]array = {{1,2,3}, {1,2,3}};
-> 이 경우 배열의 크기를 명시하지 않았지만 Java가 자동으로 2x3 배열로 크기를 정해준다

 

 

 

6.2.3. 이차원 배열에 접근하기

이차원 배열의 요소에 접근할 때도 인덱스를 사용한다. 다만, 이차원 배열에서는 행과 열을 나타내는 인덱스가 각각 필요하다.

배열명 [행 인덱스][열 인덱스];

 

 

이차원 배열을 생성하고, 값을 저장해보자. 그리고 array 배열을 그림으로 나타내면 다음과 같다.

int [][] array = new int [3][3];
//3x3 이차열 배열 생성

이제 array 배열에 인덱스를 사용해 값을 넣어보자. 현재 배열의 상태는 아래와 같다.

array[0][0] = 1;
array[0][1] = 2;
array[0][2] = 3;
array[1][0] = 4;
array[1][1] = 5;
array[1][2] = 6;
array[2][0] = 7;
array[2][1] = 8;
array[2][2] = 9;

 

 

 

 

6.2.4. 중첩 for문으로 이차원 배열 확인하기 ★★

이번에는 for문을 사용해 값이 잘 저장됐는지 확인해보자. 

일차원 배열에서는 인덱스가 1개라서 for문 1개로 충분했지만, 이차원 배열은 인덱스가 2개이다. 따라서 for문도 2개여야 한다. 즉 중첩 반복문을 사용해야한다.

 

행 인덱스가 먼저 나오므로, 첫 번째 for문에서는 행 인덱스로 배열에 접근한다. 두 번째 for문에서는 열 인덱스로 배열에 접근한다. 

int [][] array = new int [3][3];
        //3x3 이차열 배열 생성

        array[0][0] = 1;
        array[0][1] = 2;
        array[0][2] = 3;
        array[1][0] = 4;
        array[1][1] = 5;
        array[1][2] = 6;
        array[2][0] = 7;
        array[2][1] = 8;
        array[2][2] = 9;

        //for문으로 이차원 배열이 출력되도록 하기
        for (int i=0; i<=2; i++){
            for (int j=0; j<=2; j++){
                System.out.print(array[i][j] + " ");
            }
            System.out.println("");
        }

처음에는 i 하나로 인덱스 2개를 표현할 수 있지 않을까?라고 생각해서, 중첩 for문을 사용하지 않고 그냥 for문만 사용해서 코드를 작성하려고 했었다. 

근데 생각해보니 행 인덱스와 열 인덱스를 i 하나로 컨트롤 할 수 없다는 것을 깨달았다.... [i][i+1] 이런걸 생각했지만 말도 안되는 생각이었던 것이엇던 것이다.

 

 

 

6.2.5. 배열 크기 확인: length

이차원 배열도 배열 크기를 length 속성으로 알 수 있다. 나타내는 값은 일차원 배열과 조금 다르다.

  • array.length는 array 배열의 행의 수를 나타낸다
  • array[0].length는 array 배열에서 첫 번째 행의 열 개수를 나타낸다
  • array[1].length는 array 배열에서 두 번째 행의 열 개수를 나타낸다

배열 크기를 사용하도록 반복문을 다음과 같이 수정할 수 있다.

for (int i=0; i<array.length; i++){
            for (int j=0; j<array[0].length; j++){
                System.out.print(array[i][j] + " ");
            }
            System.out.println("");
        }

 

주의해야할 점이 있다. 배열의 length를 종료값으로 설정할 경우 <=가 아닌 =로 등호를 수정해줘야한다

처음에 length를 가지고 코드를 짰을 때 이런 오류가 나서(Index 3 out of bounds for length 2 at Main.main...) 살펴봤더니 범위를 벗어나서 문제가 생겼었다. 인덱스는 0부터 시작하기에, 인덱스 관점에서는 2열까지밖에 없는데 내가 3열까지 출력하라고 범위를 지정해놨으니 없는 열을 출력하지 못해 오류를 낸 것이다.

 

 

 

6.2.6. 반복문으로 배열에 값 저장하기 ★

반복문으로 이차원 배열의 값에 접근하는 방법을 알아봤다. 값을 저장할 때도 이 방법을 활용해보자.

우리는 앞서 이차원 배열에 값을 저장할 때 인덱스로 일일이 접근하는 방식을 사용했다. 값에 접근하므로 앞에서 사용한 중첩 반복무을 그대로 활용하고 출력 부분만 수정하면 된다.

 

값을 저장하는 코드는 아래와 같은 형태이다. 

array [행 인덱스][열 인덱스] = 값;

 

여기서 행 인덱스는 i변수로, 열 인덱스는 j로 치환한다. 값은 1부터 9까지 바뀌니(우리가 입력하지 않고 자동화 할 것이므로) x변수로 표시한다. 그런데 변수는 사용하기 전에 어딘가에서 선언하고 초기화해야한다. 어디서 해야할까? 반복문 안에서 초기화를 한다면 반복문을 돌때마다 값이 초기화 될것이다. 따라서 반복문 밖에 선언하고 1로 초기화하면 된다.

public class Main {
    public static void main(String[] args) {
        int [][] array = new int [3][3];

        //이차원 배열에 값을 넣는 부분
        //반복문 안에 두면, 반복문을 돌때마다 초기화됨...주의
        int x=1;
        for (int i=0; i<=2; i++){
            for (int j=0; j<=2; j++){
                array[i][j]=x;
                x++;
            }
        }

        //이차원 배열을 출력하는 부분
        for (int i=0; i<=2; i++){
            for (int j=0; j<=2; j++){
                System.out.print(array[i][j] + " ");
            }
            System.out.println("");
        }

    }
}
1. 코드에서 ++연산자를 사용하는 문장은 윗 줄과 합쳐 한 문장으로 작성해도 된다.
array[i][j] = x++;
-> [0][0]에 1의 값을 넣은 후 x값을 1 증가시킨다. [0][1]에 증가된 x값 2를 넣은 후 x값을 2 증가시킨다...(반복)

2. 또는 x를 0으로 초기화하고 ++연산자를 변수 앞에 사용하여 작성할 수도 있다.
array[i][j] = ++x;
->  x값을 1 증가시켜 1이 된 후 [0][0]에 x값인 1을 넣는다. x값을 1 증가시켜 2가 된 후 [0][1]에 x값인 2를 넣는다...(반복)

 

 

 

6.2.7. 실습: 이차원 배열로 구구단 프로그램 만들기

중첩 반복문을 사용한 구구단 프로그램을 활용해, 구구단 결과를 이차원 배열에 담은 후 배열에 담긴 값을 가져와 출력하는 형태로 작성한다. 단, 기존 코드에서는 2단~9단을 출력하는데 여기서는 1단도 포함한다. 즉 1~9에 1~9를 곱해 나온 값을 이차원 배열에 저장하고, 단별로 출력한다.

 

 

먼저 정수형 배열 gugudan을 9x9 크기로 생성한다. 그림으로 표현해보면 아래와 같다.

int [][] gugudan = new int [9][9]

public class Main {
    public static void main(String[] args) {
        int [][] gugudan = new int [9][9];

        for (int i=0; i<=8; i++){
            System.out.print("----" + (i+1) + "단 ----\n");
            for (int j=0; j<=8; j++){
                gugudan[i][j] = (i+1)*(j+1);
                System.out.print((i+1) + "x" + (j+1) + "=" + gugudan[i][j] + "\n");
            }
            System.out.println("");
        }

    }
}
int [][] gugudan = new int [9][9];
-> 9x9 사이즈의 이차원 배열

for문에서 i와 j의 값은 1로 시작하면 안됨
-> 1단부터 시작인데 왜 안됨? 이라고 묻는다면,,,, 배열의 인덱스는 0부터 시작하기 때문이라고 설명해주면 된다.

 

이렇게 이차원 배열을 구성한 것 처럼, 이차원 배열을 확장해 삼차원 배열도 구성할 수 있다. 삼차원 배열은 이차원 배열이 여러개 있다고 생각하면 도니다. 이렇게 이차원 배열 이상의 배열을 다차원 배열(multi-dimensional array)라고 한다. 실무에서도 삼차원 배열 이상은 잘 사용하지 않으며, 입문 단계에서는 이차원 배열까지만 알아도 충분하다.

 

 

 

6.2.8. QUIZ ★★

이차원 배열을 사용해 학생들의 성적을 저장해 출력하려고 한다. 빈칸에 알맞은 코드를 작성해라

 

내가 짠 코드) - 정답. 이차원 배열이다. 일차원 배열 아니다

public class Main {
    public static void main(String[] args) {
        //학생 3명의 4과목 점수를 저장하는 이차원 배열 생성
        int [][] scoreArray = {{85,70,90,95}, {80,95,90,75}, {75,85,90,80}};

        //학생 성적 출력
        System.out.println("학생들의 성적은 다음과 같습니다.");
        for (int i=0; i<=(scoreArray.length -1); i++){ //빈칸 (1)
            System.out.print("학생" + (i+1) + ":"); //학생 번호 출력
            for (int j=0; j<=scoreArray[i].length; j++){ //빈칸 (2)
                System.out.print(scoreArray[i][j] + " "); //각 과목 점수 출력, 빈칸 (3)
            }
            System.out.println("");
        }
    }
}
1. 빈칸 (2)에 나는 (1)과 똑같은 코드를 넣었지만, i번째 열의 갯수를 의미하는 scoreArray[i].length를 쓰는것이 더 명료하다.
2. 빈칸(3)에서 처음에 scoreArray[j]로 한 행을 출력하고자 했는데 오류가 났다. 
-> scoreArray[j]는 1차원 배열이고, 단순히 출력하면 int[] 배열의 메모리 주소를 출력하려고 하다가 오류가 난다. scoreArray는 2차원 배열이지만, scoreArray[j]는 일차원 배열이라는 것을 생각해야한다.

6.3. 배열 심화

6.3.1. 참조 자료형으로서의 배열 ★★

3장에서 문자열은 참조자료형이라고 설명했었다. 이 장에서 배운 배열도 문자열과 마찬가지로 참조 자료형이다.

참조 자료형실제 값이 아닌 메모리 주소를 저장하는 변수의 자료형이다. 참조란, 실제 값이 아닌 주소를 저장하는 것을 의미한다. 그래서 메모리 주소를 저장하는 변수참조 변수(reference variable)라고 한다.

 

자바의 메모리 구조와 함께 참조 자료형을 이해해보자.

자바 프로그램이 JVM(자바 가상 머신)을 통해 실행되면, 운영체제로부터 프로그램을 실행하는데 필요한 메모리를 할당받는다. 이때 할당받은 메모리 영역을 런타임 영역(runtime data area)라고 한다.

 

○ 스택 영역(Stack)

: 메서드 호출시 지역변수, 매개변수, 함수 호출내역 등이 저장되는 영역

 

○ 힙 영역(Heap)

: 힙은 객체와 배열이 할당되는 영역이다. 자바에서는 new 키워드로 객체와 배열을 생성하며, 생성된 객체와 배열의 크기에 따라 크기가 동적으로 변하는 특징을 가지고, 모든 Thread에서 공유되는 특징을 가진다.

 

 

일반 변수(기본 자료형 변수)는 이 중에서 스택(Stack)에 값을 저장한다. 예를 들어 아래와 같은 코드가 있을 때, 스택에 할당된 영역을 a변수가 가리키고 -> 여기에 10이 저장되며 초기화된다.

int a = 10;

반면 참조 변수스택에 할당되고, 실제 값은 힙(Heap)에 저장된다. 변수에는 값이 저장된 힙의 주소가 저장된다. 따라서 참조 변수는 "저장된 주소"에 의해 "힙의 값"에 접근할 수 있다.

 

코드와 함께 살펴보자. 코드에서 new 키워드가 중요한 역할을 한다. 

new 키워드는 힙에 새로운 공간을 할당하고 할당된 공간에 배열을 생성한다. 여기서는 크기가 5인 int형 배열을 생성하므로 총 20바이트의 연속된 메모리 공간이 할당된다. (1) new 키워드는 힙에 생성된 배열의 첫 번째 요소의 주소를 반환한다. (3) 반환된 주소는 스택 영역에 있는 numbers 변수에 저장된다. (3) numbers 변수는 저장된 주소로 배열의 요소에 접근한다.

int [] numbers = new int[5];

 

그림에서 numbers 변수에 저장된 0x200은 배열의 첫 번째 요소가 저장된 주소이다.

 

 

 

6.3.2. 배열의 복사(얕은 복사, 깊은 복사)

일반 변수일때 다음과 같이 작성하면 변수의 값을 다른 변수에 복사할 수 있다. 기본 자료형은 값 자체를 복사하기 때문에 b 변수의 값은 1이 된다. 이후 a변수의 값을 변경해도 b변수의 값에는 영향을 미치지 않는다.

int a=1;
int b=a;

 

그렇다면 참조변수는 어떨까? 다음 코드에서 originArray 변수가 저장하고 있는 값은 {1,2,3} 배열의 첫 번째 요소의 주소이다. 실제 값이 아닌 배열을 참조하는 것이다. 즉 copyArray 변수도 {1,2,3} 배열의 첫 번째 요소의 주소를 저장한다. 복사를 했으니 이제 copyArray 변수도 인덱스로 {1,2,3} 배열의 각 요소에 접근할 수 있다.

int [] originArray = {1,2,3};
int [] copyArray = originArray;
System.out.println(copyArray[0]);
System.out.println(copyArray[1]);
System.out.println(copyArray[2]);

 

다음과 같이 copyArray 변수로 배열의 첫 번째 요소를 변경해보자. 이 코드는 copyArray 변수가 참조하는 배열의 첫 번째 요소를 10으로 변경한다. 그런데 copyArray와 originArray 변수는 같은 배열을 참조한다. 따라서 originArray 변수가 가리키는 배열도 첫 번째 요소가 10으로 변경된다.

copyArray[0] = 10;
System.out.println(originArray[0]);

 

이렇게 배열을 복사했을 때 동일한 배열을 가리키는 것얕은 복사(shallow copy)라고 한다. 얕은 복사는 배열의 참조, 즉 주소만 복사한다. 예제에서 봤듯이 얕은 복사를 하면 한쪽에서 값을 변경했을 때 다른 쪽에도 영향을 미치므로, 데이터 관리가 중요한 상황에서는 주의해서 사용해야한다.

 

 

만약 원본 배열과 독립적인 복사본이 필요하다면 얕은 복사가 아닌 깊은 복사(deep copy)를 사용해야한다. 깊은 복사는 배열의 모든 요소를 복사해 새로운 배열을 생성한다. 깊은 복사된 배열은 원본 배열과 별개의 메모리 공간에 존재하며, 따라서 한쪽을 수정해도 다른 쪽에 영향을 미치지 않는다.

 

깊은 복사를 하는 가장 간단한 방법은 모든 요소를 하나하나 복사하는 방식이다. deepCopyArray 배열을 originArray 배열고 같은 크기로 생성한 후, for문으로 originArray 배열의 요소를 각각 복사한다. deepCopyArray 배열은 originArray 배열과 독립적으로 존재하기 때문에 deepCopyArray[0]으로 배열의 첫 번째 요소를 변경해도 originArray 배열에는 영향을 미치지 않는다.

int [] originArray = {1,2,3};
int [] deepCopyArray = new int[originArray.length];

for (int i=0; i<originArray.length; i++){
	deepCopyArray[i] = originArray[i];
}

deepCopyArray[0] = 10;
System.out.println(originArray[0]); //깊은 복사이므로 1이 출력된다

 

 

 

 

6.3.3. QUIZ

다음 코드를 실행했을 때 어떤 결과가 출력되는지 작성하시오

 

내 답변) - 정답

현재 copy 배열을 original 배열의 크기와 동일한 크기로 만들었고, for문으로 original 배열의 값들을 copy 배열에 복사하고 있다. 현재 깊은 복사가 진행되고 있으므로, copy와 original 배열은 독립적으로 존재한다. 따라서 4라는 결과물이 출력된다.

int [] original = {1,2,3,4,5};
int [] copy = new int[original.length];

for (int i=0; i<original.length; i++){
	copy[i] = original[i];
}

copy[3]=99;
System.out.println(original[3])
얕은 복사
int [] originArray = new int[3]  or  int [] originArray = {1,2,3}
int [] copyArray = originArray;
-> 간단하게 이렇게 하면 됨!

마무리

1. 배열의 기본

1) 배열은 변수가 여러 개 연속해 있는 개념으로, 여러 값을 변수명 하나로 묶어 저장한다.

2) 배열은 다음과 같이 선언한다

-> 자료형 [] 배열명;

3) 배열을 사용하려면 생성해야한다. 값을 넣어 초기화하거나 배열의 크기로 생성할 수 있다

->자료형 [] 배열명 = {값1, 값2, ...};
-> 자료형 [] 배열명 = new 자료형[배열의 크기];

4) 배열의 크기배열에 저장할 수 있는 값의 최대 개수이다. 배열 크기는 "배열명.length"로 알 수 있다 -> 인덱스처럼 0부터 시작하는게 아니다!! 헷갈림 주의

5) 배열에 저장된 각 값을 요소라고 한다. 요소의 위치는 인덱스로 나타낸다. 인덱스는 대괄호 안에 넣어 표시하며, 숫자 0부터 시작한다. 인덱스로 특정 요소에 접근해 값을 저장하거나 변경할 수 있다.

 

2. 배열과 문자열

1) 배열에 문자열을 담을때배열을 선언한 변수 앞에 String을 붙인다. (어찌보면 당연한...)

-> String [] fruits = {"Apple", "Banana", "Chrry", "Durian"};

 

3. 이차원 배열

1) 이차원 배열은 2개 이상의 행으로 구성된 배열로, 공간이 행과 열로 나열된 형태이다

2) 이차원 배열을 생성하는 방법은 2가지이다

-> 자료형 [][] 배열명 = {{값1, 값2, ..}, {값1, 값2, ...}, ...};

-> 자료형 [][] 배열명 = new 자료형[행 크기][열 크기]

3) 이차원 배열의 요소는 2개의 인덱스로 접근한다

-> 배열명 [행 인덱스][열 인덱스];

4) 이차원 배열의 배열 크기는 length 속성으로 알 수 있다.

-> 배열명.length: 이차원 배열의 행의 수를 나타낸다

-> 배열명[0].length: 이차원 배열의 첫 번째 행의 열 개수를 나타낸다

 

4. 배열 심화

1) 배열실제 값이 아닌 메모리 주소를 저장하는 참조 자료형이다. 이때 메모리 주소를 저장하는 변수를 참조 변수라고 한다.

2) 자바 프로그램이 실행되며 메모리를 할당받는데, 이를 런타임 데이터 영역이라고 한다

3) 참조 변수는 스택에 할당되고, 실제 값은 힙에 저장된다 -> 참조 변수에는 값이 저장된 힙 영역의 주소가 저장된다. 참조 변수는 이 주소를 통해 힙의 값에 접근할 수 있다.

4) 배열을 복사했을 때 동일한 배열을 가리키는 것을 얕은 복사라고 한다. 얕은 복사는 배열의 주소만 복사한다

5) 원본 배열과 독립적으로 동작하는 배열을 복사하는 것을 깊은 복사라고 한다. 깊은 복사는 배열의 모든 요소를 복사해 새로운 배열을 생성한다.


셀프 체크

이차원 배열을 사용해 학생들의 각 과목 점수와 점수 평균을 출력하려 한다. 다음과 같은 결과가 나오도록 프로그램을 작성해라

 

내가 짠 코드)

        int [][] array = {{85,70,90,95,0}, {80,95,90,75,0}, {75,85,90,80,0}};

        //평균 계산하기
        for (int i=0; i<array.length; i++){
            int sum=0;
            for (int j=0; j<array[0].length; j++){
                sum+=array[i][j];
            }
            array[i][4]= sum/(array[0].length -1);
        }

        System.out.println("학생들의 성적은 다음과 같습니다.");
        for (int k=0; k<array.length; k++){
            System.out.print("학생"+(k+1)+":");
            for (int l=0; l<(array[0].length-1); l++){
                System.out.print(array[k][l]+" ");
            }
            System.out.print(" | 평균:"+(double)array[k][4]+"\n");
        }
(double)array[k][4]로 명시적 형 변환을 해주었음. 이 경우 int -> double이 되는것이니 문제가 발생하지 않음

+) 진짜 감사합니다ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ 엄청 길게 작성했는데 네트워크 튕겨서 다 날아가는줄 알았어요ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ