본문 바로가기

별걸다하는 IT/프로그래밍언어

[Java, C, C++ ] 배열이란, 배열 선언 및 초기화 - 프로그래밍기초

[Java, C, C++ 프로그래밍 완전정복 목차]

 

오늘 포스팅: 배열 (Array) 기초

항상 프로그래밍 포스팅은 무엇을 할까 고민되는 것 같아요 ㅎㅎ

배열도 워낙 무궁무진해서리... 범위를 우케 나눠야 나중에 꼬이지 않을까 고민하게 되네요 ㅎㅎㅋㅋㅋ

오늘 다뤄볼 내용은 배열입니다. 배열의 개념은 모든 언어의 공통이자 기본적인 개념이기 때문에 모든 언어를 한 줄 한 줄 이해하려고 하기보다는 flow~흐름을 잡으려고 노력해보아요! 

 

배열이란 왜 필요한가 ?

한 반에 학생이 3명일 때, 반의 평균을 구하는 프로그램을 만들어달라는 요청을 받았어요.

고럼 아마 여러분들은 이렇게 만들거예요.

~자바의 경우~
package test;
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
        //입력받기 위한 사전작업
		Scanner sc = new Scanner(System.in);
		//아리, 쌤, 조이 학생의 성적을 각각 입력받습니다.
		int ariScore = sc.nextInt(); //아리점수 입력받기
		int samScore = sc.nextInt(); //쌤 점수 입력받기
		int joyScore = sc.nextInt(); //조이 점수 입력받기
        //평균 구하기
		float avg = (float)(ariScore+samScore+joyScore)/3;
        //출력
        System.out.println(avg);
	}
}
~C/C++의 경우~
#include <stdio.h>
int main(void)
{
     //입력받을 변수 선언
     int ari_score, sam_score, joy_score;
     //입력받기 
     scanf("%d %d %d", &ari_score, &sam_score, &joy_score);
     //평균 구하기
     float avg = (float)(ari_score+ sam_score+ joy_score)/3;
     printf("%.2f", avg); // 출력하기
     return 0; // 끝내기
}

근데 여러분... 만약 학생이 100명이면... 이거 어떻게 바꿀거예요..? 아무리 우리가 Ctrl+C, Ctril+V에 능하다고 해도..

//자바
int ariScore = sc.nextInt();  int samScore = sc.nextInt();
int joyScore = sc.nextInt();  int stu4Score = sc.nextInt();
int stu5Score = sc.nextInt();  int stu6Score = sc.nextInt();
...

이 부분을 100개 만들거예요..? ㄷㄷㄷ 완전 개 노가다 작업이 되겠죠? ㅎㅎ 그러다가 만약에.. 문제 오류가 있어서 모든 학생의 점수를 +5점씩 추가 점수를 줘야 하는 상황이 발생했어요. 와우~

ariScore += 5; samScore += 5; joyScore += 5; 
...이 짓을 100번... 

네.. 거의 사람을 의미 없이 기계처럼 노동시키는 프로그램이 됩니다. 이게 1000명이 된다면..? 고객한테 수정사항이 여기저기서 요청되면..? 하루만에 퇴사할거예요 ㅎㅎㅋㅋㅋ

 

이런 일을 없도록 하기 위해 생겨난 것이 배열입니다. 배열은 확장성도 높이고, 유지보수성도 좋게 하고, 반복되는 코드도 줄이고 등 한마디로 작업 효율성을 높이기 위해 여러 변수들을 묶음으로 관리할 수 있게 해주는 겁니다.ㅎㅎ

고럼 배열이 뭐길래 이를 가능케 하는지 알아볼까요?

 

배열이란

배열은 묶음이라 했죠? 여러 개의 값을 저장할 수 있어요.

배열은 같은 타입의 데이터를 연속된 공간에 나열시키고, 각 데이터에게 번호표를 줘서 어디에 저장했는지 쉽게 알 수 있게 한 타입이예요.

 

C배열 vs 자바 배열

그런데 살짝 알아두면 좋을 것이,,, C언어에서 배열과 JAVA 배열이 조금 차이가 있습니다. C언어 배열을 사용하다가 좀 더 편리하게 사용했으면 좋겠다~ 해서 JAVA를 C언어로 만들 때, C언어 배열에 여러가지 기능을 포함시켜서 패키지처럼 좀 더 사용하기 간편하게 재구성했거든요 ㅎㅎ (배열이 객체로 구현되었다라고 하는데, 나중에 클래스 목차 들어가게 되면 자연스레 이해하게 됩니다.)  

 

만약 배열을 사용한다면?

위 프로그램이 만약 배열을 사용해서 짰었으면 어떻게 줄여졌을까요?

//자바
 //입력받기 위한 사전작업
Scanner sc = new Scanner(System.in);
//백명의 학생의 성적을 저장해줄 배열입니다.
Integer stuScore[] = new Integer[100];
//백명의 학생 성적 입력받아서 배열에 저장해주기 
for(int index=0; index<100; index++)
	stuScore[index] = sc.nextInt();

무려 100명의 학생 성적을 입력받는 것이 for문 단 두 줄로 끝날 수 있게됩니다.

 

배열 선언과 초기화

먼저 배열을 사용해보려면 배열을 선언하는 법을 알아야겠죠.

 

1. 배열 선언

배열은 대괄호( [,] )로 표기합니다.

※ C언어의 배열선언

//C, C++
타입 변수[개수];

참고, 자바의 경우 대괄호가 타입뒤에 올수도 있고 앞에 올수도 있어요. (밑에 나옴)

 

▶배열 선언시 공간할당

변수 포스팅에서 선언은 메모리에 공간을 할당하는거라고 언급했었는데, 배열의 경우 어떻게 할당이 될까요?

int arr[6];

6개의 정수를 배열에 저장한다는거~

 

 

 

 

 

이렇게 할당이 됩니다!

주소는 RAM 즉 휘발성이기 때문에 프로그램을 실행할때마다 변경되어요.

여기서 알 수 있는 걸 정리해볼까요?

그림을 보니까 6개의 공간이 나란히 잡혀있네요

 

★즉, 대괄호 안의 수만큼 메모리에 공간이 잡힌다!!

★ 근데 이 공간들은 메모리에 연속적으로 잡힌다.

★ 그리고 순서대로 번호가 부여되는데 0번부터 시작한다. (이렇게 각 공간을 구별하기 위해서 붙여진 번호를 인덱스(index)라고 합니다.

 

 

 

 

 

 

 

 

 

 

배열은 왜 같은 타입이여야하는가? 타입은 왜 필요할까?

타입별로 메모리에 할당되는 크기가 다르다고 했던 것 기억하시나요? (기억안나는 분은 변수편 참고하고 오기~)

예를 들어 int a; 이렇게 선언하면 4바이트가 할당되고, char c; 이렇게 선언하면 1바이트가 할당된다고 했어요

위의 그림을 다시한번 살펴보면 6개의 공간이 모두 동일한 크기라는 걸 알 수 있습니다.

그런데 조금만 더 자세히보면~ 각 공간이 모두 4바이트예요~!!

즉, int arr[6];하고 선언하면, '6개의 공간을 만들되, 정수를 저장할 것이므로 각 공간은 4바이트로 할당하여라~' 라는 의미가 되는거죠!

(cf. 참고로 원래대로라면 자바랑 C언어처럼 모두 동일한 타입을 배열로 묶어줘야 하지만, 더 유연성이 높은 언어의 경우 서로 다른 타입의 혼합을 허용하는 언어도 있습니다. ex)javascript )

 

※ JAVA언어의 배열선언

//Java의 경우는 대괄호를 타입 앞 뒤에 위치시켜도 됩니다.
타입 변수[];
타입[] 변수;
int arr[];
int[] arr;

선언시 대괄호 안에 개수를 넣어주면 안돼요!

 

▶배열 선언시 공간할당

자바의 경우, C언어와 다르게 객체로 구성되어 있기 때문에 (그냥 배열에서 많이 쓰는 기능들까지 싸그리 포함해서 정의를 새로 내렸줬다고 이해해도 됨) 공간할당이 살짝 상이합니다.

아주 아주 약간만 깊게 조금 더 들어가서 설명을 해주자면,,

(이해안되시는 분은 넘겨도 되는 구간~, 배열 선언과 초기화 방법만 알아도 돼요)

메모리 내부에서도 공간이 여러개가 나뉘어져 있어요.

그 중 STACK이라고 하는 공간이 있고, HEAP이라고 하는 공간이 있습니다.

C언어의 경우 위 그림처럼 메모리가 할당되는 것이 다 STACK에서 이루어집니다. 그런데 JAVA의 경우, 선언은 STACK에서 이루어지고 실제 배열 생성은 HEAP이라는 공간에 생성됩니다.

따라서 선언만 했으면, JAVA의 경우 공간할당은 나중에 배열이 생성되는 공간을 기억해둘 4byte 메모리만 할당됩니다. 즉 나머지 공간할당은 배열이 실질적으로 생성되는 초기화때 이루어진다!

 

2. 배열 초기화

※ C언어의 배열 초기화

int arr[6]; //배열 선언 ↓배열초기화 arr[0]=10; arr[1]=20; arr[2]=30; arr[3]=40; arr[4]=50; arr[5]=60;

int arr[6]; //배열 선언
↓배열초기화
arr[0]=10; arr[1]=20; arr[2]=30;
arr[3]=40; arr[4]=50; arr[5]=60;

이와 같이 인덱스를 이용해 각각의 공간에 접근해서 값을 넣어줄 수도 있고

int arr[6]; //배열 선언
for(int i=0; i<6; i++)
     arr[i]=10*(i+1);

이렇게 반복문을 이용해서 값을 넣어줄 수 있습니다. 

요렇게 들어가겠죠? ㅎㅎ

※ C언어 - 선언과 초기화를 동시에?

물론, 배열에서도 선언과 초기화를 동시에 해줄 수 있습니다.

int arr[6] = {10,20,30,40,50,60}; 
//순차적으로 10, 20, 30, 40, 50, 60으로 초기화~

근데 선언과 초기화를 동시에 해 줄 경우에는 대괄호 안에 개수를 명시해놓지 않아도 컴파일러가 자동으로 개수를 세서 넣어줍니다.

int arr[] ={10,20,30,40,50,60};

개수를 지정했는데 그만큼 채우지 못했을 경우, 남은 공간은 모두 0으로 채워집니다.

int arr[6] ={10,20}; //3,4,5번째 공간은 0으로 채워짐

근데 선언과 초기화를 따로 하는데 이렇게 값 대입식으로 해주면 에러입니다.

int arr[6]; arr = {10,20,30,40,50,60}; 에러!

※ JAVA언어의 배열 초기화

자바의 경우 선언과 초기화를 따로따로 할 경우에는~

배열 선언부 ↓
int[] arr; //또는 int arr[];
배열 초기화 ↓
arr = new int[6]; //HEAP에 6개의 공간을 잡고 0을 넣습니다.

배열의 경우 이렇게 초기화를 해주면 default값인 0으로 채워집니다.

이후에 값을 넣고 싶으면 C언어 예시처럼 각 공간에 직접 접근해서 값을 넣어주거나, 반복문을 이용해서 넣어줍니다.

arr[0]=10; arr[1]=20; arr[2]=30;
arr[3]=40; arr[4]=50; arr[5]=60;
또는
for(int i=0; i<6; i++)
     arr[i]=10*(i+1);

그런데 자바는 객체특성 때문에 new연산자를 사용해서 아래처럼 값을 채워줄 수 있어요 

Integer arr[];
arr = new Integer[] {1,2,3};

※ JAVA언어 - 선언과 초기화를 동시에?

마찬가지로 값 목록으로 배열을 생성할건데요. JAVA또한 C언어처럼 값 목록으로 초기화하는데 new를 사용하지않고 선언부를 분리해주면 에러가 납니다. (new는 객체특성)

타입[] 변수;
변수 = {값0, 값1, 값2, ..}; //컴파일 에러
대신 아래로 대체해줍시다.
변수 = new 타입[] {값0, 값1, 값2, ..}; 

값으로 초기화했을 때, 마찬가지로 크기를 넣지 않아도 컴파일러가 자동으로 세서 삽입해줍니다.

int arr[] ={10,20,30,40,50,60}; OK

오늘 배운거 확인하기

▶배열이 왜 필요한지, 배열이 무엇인지 안다.

▶배열을 선언하고 초기화 하는 방법을 알고 있다.

▶인덱스가 무엇인지 안다.

▶인덱스는 1부터 카운팅이 아니라 0부터 시작된다.

▶배열 생성시 공간 할당이 어떻게 이루어지는지 알고 있다.

▶C/C++ 배열과 JAVA 배열의 차이점을 안다.

 

배열 선언과 초기화만 했을 뿐인데.. 두 가지 언어를 동시에 해서 그런가 포스팅이 길어졌네요ㅎㅎㅎ 언넝 자야겠어요 ㅎㅎ 오늘은 여기까지~!!

항상 광고보답, 댓글 공감 등의 응원은 꾸준히 질좋은 포스팅을 쓰고자 노력하는 저에게 큰 힘이 됩니당 :)