백엔드/코드스테이츠 수강

코드스테이츠 수강_3주차_4일차_JAVA기초 (배열)

반 불혹 2022. 9. 1. 22:03

코드스테이츠 수강 3주차 4일차 배열에 대해 배웠다.

1. 배열이란?

우리가 앞서 배운 변수들은 변수 하나당 한개의 데이터밖에 저장 하지 못한다.

이게 뭔말이냐고? 

int num = 100;         -> 정수 100을 저장함

char A = 'A';             -> 글자 A를 저장함

String ABC - "ABC"; -> 문자열 ABC를 저장함

위의 예시 모두 "하나"의 "데이터"만 넣을 수 있다.

이전 글에서 설명한 것 처럼 해당 변수들은 데이터를 저장하기 위해서 지정된 크기의 공간을 할당하고, 그 공간 안에 데이터를 저장한다.

만약 7월 1일 부터 31일까지 기온을 double 형으로 저장한다고 치면 

double temperatureOfJuly1  = 28.1;
double temperatureOfJuly2  = 30.2;
...
double temperatureOfJuly31 = 32.3;

이캐캐 일일히 코드를 써줘야 한다는 것이다. 

이 때, 메모리에 어떤식으로 저장되느냐?

위는 주소값, 아래는 데이터값 (출처 : 코드스테이츠)

double형이 들어갈 수 있는 빈 공간 메모리에 이렇게 마치 흩어진것 처럼 각각 값을 저장한다. 

하지만, 배열을 사용하면 이 31개의 값들을 한 변수에 다 저장 가능하다. 

double[] temperatureOfJuly = { 27.4, 30.1, ..., 31.8 };

7월1일의 기온은 첫번째로, 2일은 두번째로... 31일까지 지정해준다.

이 때 배열이 메모리에 저장되는 방식은 아래와 같다.

 

주소 따로, 데이터 따로 저장된다, 하지만 데이터는 줄줄줄 연속되서 저장된다. (출처 : 코드스테이츠)

변수명인 temperatureOfJuly은 뒤에 후속해오는 데이터중 첫번째 데이터의  "주소값"을 저장한다. 

고로, temperatureOfJuly을 불러오면 주소값이 나오고, 그 주소값으로 가면 우리가 원하는 31개의 줄줄 데이터가 있다는 것이다!

이때, 첫번째 데이터, 두번째 데이터...등의 위치를 나타내기 위해 번호를 부여 받는데 이를 인덱스(index)라고 한다.

주의할것은 컴퓨터는 0부터 세기 때문에 첫번째는 0, 두번째는1.....순으로 증가한다.

 

배열에서 변수명이 주소값을 가진다고?

앞에서 temperatureOfJuly을 불러오면 주소값이 나온다 했다.

변수를 불럿을때 데이터 말고 주소를 내놓는 애를 참조변수 라고 한다.

왜 이놈은 참조변수일까?

답은 간단하다. 

"콤퓨타가 우리가 배열에 얼마나 쳐넣을지 몰라서" 이다.

이전에 배열이 아닌 변수는 (String제외)는 데이터의 크기가 정해져 있기 때문에 선언과 동시에 공간을 할당 가능했지만, 배열은 우리가 입맛대로 넣기 때문에 얼마가 들어올지, 들어오기 전까지는 알 수가 없다!

그래서 뒤에 들어올 데이터의 첫 부분의 주소만 적어놓으면 뒤에서 들어온 데이터를 그냥 줄줄줄 대리고 오기만 하면 된다.

그런데, 줄줄줄....언제까지...?

그래서 배열을 사용 할 때 배열의 크기를 지정하는것을  빼먹으면 안된다.

 

2.  2차원 배열

위에서 보여준것은 1차원 배열이다. 단순히 주르르륵 쓴 배열

2차원 배열은 배열 안의 요소를 배열로 넣은것이다.

작성 예시 

int[][] num;
num = new int[31][3];

위의 코드는 31개의 요소에 3개의 요소를 가진 배열을 넣은 배열이다. 

이게 어떤식으로 생겼냐?

{
	{ 0, 0, 0 },
	{ 0, 0, 0 },
	{ 0, 0, 0 },

	...

	{ 0, 0, 0 }
}

이캐캐 생겼다. 

요소 { 0, 0, 0 } 가 31개 쥬르르르륵 있는 것이다.

생긴게 꼭 행렬과 비슷한데, 사실 값을 불러올때도 비슷하다.

만약 저기서 3행 1열에 해당하는 데이터를 얻고 싶으면?

num[2][0]; 을 불러오면 된다! (콤퓨타는 0부터 세므로 0, 1, 2 -> 2가 3번째 값이다!)

2차원 배열 말고도 3차, 4차원도 있는데 거의 사용하지 않는다... 2차원까지만이라도 잘 하자!

 

 

3. 가변 배열

2차원 배열은 1차원 배열보다 자유로운 형대로 배열을 만들 수 있다. 

배열이 2차원 이상일 때 마지막 차수에 해당하는 배열의 길이를 고정하지 않아도 된다.

예시) int[][] num = new int [30][]; -> 맨 뒤의 배열 크기는 안써도 된다!

int[][] ages = new int[5][];

ages[0] = new int[5];
ages[1] = new int[6];
ages[2] = new int[7];
ages[3] = new int[8];  
ages[4] = new int[9];

System.out.println("Arrays.toString(ages[0]) = " + Arrays.toString(ages[0]));
System.out.println("Arrays.toString(ages[1]) = " + Arrays.toString(ages[1]));
System.out.println("Arrays.toString(ages[2]) = " + Arrays.toString(ages[2]));
System.out.println("Arrays.toString(ages[3]) = " + Arrays.toString(ages[3]));
System.out.println("Arrays.toString(ages[4]) = " + Arrays.toString(ages[4]));

// 결과
// Arrays.toString(ages[0]) = [0, 0, 0, 0, 0]
// Arrays.toString(ages[1]) = [0, 0, 0, 0, 0, 0]
// Arrays.toString(ages[2]) = [0, 0, 0, 0, 0, 0, 0]
// Arrays.toString(ages[3]) = [0, 0, 0, 0, 0, 0, 0, 0]
// Arrays.toString(ages[4]) = [0, 0, 0, 0, 0, 0, 0, 0, 0]

그러니까 첫번째 배열의 크기(행의 갯수) 만 지정하면, 두번째 배열(열)은 넣는대로 알아서 만들어준다. 

 

4. 배열 탐색

배열은 for, while문으로 하나하나 조회 하는것이 가능한데, 눈여겨 봐야 할 것은 향상된 for문이다. 

향상된 for문은 파이썬의 for문 처럼 배열 그대로를 이용해서 for문을 돌릴 수 있다. 

int[] scores = { 100, 90, 85, 95, 100 };
int sum = 0;

for (int score: scores) {
	sum += score;
}
System.out.println(sum); // 470

위의 코드를 보면 scores의 원소를 그대로 for문에 반영한다. 

for문은 scores의 요소 갯수만큼 동작하고, scores의 요소를 하나하나 가져와서 더할 수 있다.

주의할 점은 향상된 for문 으로는 기존 배열(scores)의 값을 변하게 할 수 없다. 

 

오늘도 많이 배웠다. 생각보다 내가 기초를 많이 모르는것인지, 코드스테이츠가 세부적인것도 알려주는것인지, 오늘은 자주 사용하면서도 모르는 이야기들이 많았다. (배열의 메모리 저장 방식이라던가, 가변배열이라던가..)

앞으로도 새로운걸 보면 곡 기록해놓고 종종 들여다 봐야 겠다. 알고 모르고 차이가 코드작성에서 엄청난 것 같다.