3. 자료의 형태(data type) : 상수, 변수, 배열, (구조체), 클래스 그리고 사용자 정의 자료형.
개념적인 부분을 중심으로 설명을 할 것이기 때문에 특정 언어에 종속된 소스 코드 작성을 지양하려 한다.
그렇지만 필요할 경우 pseudocode 라고 하는 의사어 코드를 사용하려 한다.
의사어 코드는 일반적으로 알고리즘을 어떻게 구현할지 등을 전달 할 목적으로 일반적인 언어를 사용해 모델링 하는데 쓰인다.
여기서는 알고리즘이 아닌 내용 전달을 위한 용도로 사용할 예정이다.
의사어 코드가 사람마다 문법이 달라 보통 서두에 약속을 하는데, 그럴 필요 없을 정도의 수준으로 작성할 예정이다.
1. 상수 (constant, literal)
상수를 사전에 찾아보면 '변하지 않고 항상 같은 값을 가지는 수' 를 뜻한다.
그래서 보통 1, 2, 3 과 같은 숫자를 생각할 수 있지만 프로그래밍에서는 보통 다음과 같이 얘기한다.
'변하지 않는 수'
이렇게 얘기하면 '에이 그게 그거잖아' 할 수 있지만 차이가 있다.
위에서 말한 숫자들은 모두 상수라고 할 수 있겠지만, 컴퓨터에서 말하는 상수는 1, 2, 3 이외에도 존재하기 때문이다.
마지막으로 타이틀 옆에 constant와 literal 이라고 적었다.
안타깝게도 본 글의 목적에 벗어나는 내용이다.
2. 변수 (variable)
상수와 반대되는 개념으로 변수가 있다.
사전을 찾아보면 '계속 변하는 값이면서, 그 값을 저장하는 공간' 이라 정의하고 있다.
사견을 더하면 '계속 변하는 값' 이라기보다 '변할 수 있는 값' 이라고 하고 싶다.
예를 들어 수학 문제를 보면 다음과 같은것을 쉽게 볼 수 있다.
여기서 우리는 이 x를 변수라고 부른다.
위 문제에서 부등식의 참 거짓 여부를 떠나 우리는 x에 정수인 어떤 값이든 넣어볼 수 있다.
일반적으로 수학에서 보던 변수와 프로그래밍에서의 변수는 매우 흡사하다.
이런 변수를 다른 관점에서 한 번 살펴보려 한다.
바로 크기의 관점이다. 수학에서 변수의 범위를 한정하는 (위의 예시에서 정수) 것과 비슷한것 같지만 조금 다르다.
일상의 예를 들어 체육 활동과 관련된 교구들을 정리한다고 생각하자.
교구들에는 탁구공, 야구공, 축구공, 허들, 철봉 등 다양한 종류가 있다.
모두 한 곳에 몰아 넣어 보관할 수 있지만, 그랬다가는 필요할 때 한참을 찾아야 할지 모른다.
그래서 보통 스포츠 종목에 따라 분류하거나 도구의 크기에 따라 분류해서 보관한다.
자료형도 종류와 크기에 따라 서로 다른 공간에 나누어 담을 수 있도록 해두었다.
정수는 정수끼리, 실수는 실수끼리.
정수 안에서도 작은 숫자를 담는 공간과 큰 숫자를 담는 공간.
자바에서의 기본 자료형을 정리하면 다음과 같다.
종류 | 타입 | 크기 |
byte | 정수 | 8 bit (1 byte) |
short | 16 bit (2 byte) | |
int | 32 bit (4 byte) | |
long | 64 bit (8 byte) | |
float | 실수 | 32 bit (4 byte) |
double | 64 bit (8 byte) | |
char | 문자 | 16 bit (2 byte) |
boolean | 논리 | 1 bit |
정수 타입만 봐도 벌써 크기에 따라 네가지 종류가 있다.
같은 타입에도 크기에 따라 여러 종류가 있는지 이해하기 위해 잠시 체육관 상황으로 가보자.
탁구공과 축구공을 상자에 담아 보관하려 한다.
이때 규칙이 하나 있다. 하나의 상자에는 하나의 공만 담아 보관해야 한다.
축구공이 들어갈만한 크기의 상자에 탁구공을 하나 넣었다고 하자.
장점이라면 탁구공의 형태가 유지된다.
단점이라면 탁구공이 상자에 비해 너무 작아 공간을 낭비한다.
그럼 탁구공이 들어갈만한 크기의 상자에 축구공을 하나 넣었다고 하자.
장점..은 모르겠고 들어갔을지도 의문이다.
만약 넣었다고 하자. 탁구공 상자를 보여주며 '이곳에 축구공을 넣었어' 라고 하면 그 안에 들어간 축구공이 온전할거라 생각할 수 있을까?
바람을 뺐든 조각을 내서 넣었든 (그래도 들어갔을지 모르겠지만) 온전한 형태의 축구공을 상상할 수 없다.
(뭐.. 공간을 절약 했다고 할 수 있을지도..)
같은 공이어도 그 크기에 따라 어떤 상자에 담아야 공간 낭비를 줄이고 보관할 수 있다.
변수도 동일하게 생각하자.
4byte 크기의 정수를 short 타입의 변수에 담으면 어떻게 될까?
담겼을지 모르겠지만 담겼다고 한들 값이 망가졌을지도 모른다.
반대의 상황으로 2byte 크기의 정수를 long 타입의 변수에 담았다고 하자.
잘 담기야 했겠지만 공간 낭비다.
** 여기서 다루기에 적합하지 않지만 생각 난 김에 정리해두려 한다.
자바에 byte나 short 변수가 있지만 일반적으로 1byte, 2byte 크기의 변수를 저장할 때에도 int 타입의 변수를 사용한다.
그 이유는 JVM이 메모리 스택을 쌓을 때 4byte 단위로 저장하기 때문이다.
byte나 short와 같은 1byte, 2byte 사이즈의 자료형 변수들도 메모리에 저장할 때는 내부 변환에 의해 4byte 크기에 넣게 된다.
1byte면 8비트로 최상위 비트를 부호 비트로 사용한다고 했을 때, 양수 최대값은 2의 7제곱 빼기 1 (0을 포함하기 때문) 이다.
즉, 127이란 말인데 4byte인 경우 32비트로 동일 조건으로 계산해보면 약 21억의 숫자를 저장할 수 있는 공간에 127을 넣는다니.
심지어는 내부 변환으로 인해 더 느리다.
그럼 왜 이런 자료형을 만들었을까?
하지만 이런 경우는 변수가 단독으로 사용되었을 때 얘기다.
이건 또 무슨 소리.
결론부터 얘기하면 배열로 가면 얘기가 달라진다.
지역변수를 선언하게 되면 메모리의 stack영역에 할당 된다.
이 stack 영역은 4byte 단위로 저장되기 때문에 byte, short 타입이어도 1byte, 2byte 쪼개서 관리하지 않고 4byte 크기로 잘라 사용한다.
그래서 내부에서 두 번 일하지 않도록 정수는 int 타입을 사용하는게 좋다.
하지만 배열같은 경우 메모리의 heap 영역에 할당 되고 stack 영역에는 주소(reference)가 저장 된다.
그래서 byte 변수 10개를 선언하면 40byte 를 할당하고, 길이 10인 byte배열을 선언하면 10byte + 배열 오버헤드 만큼 할당한다.
잘 전달 되었는지 모르겠지만,
결론은 이렇다.
배열이나 클래스의 인스턴스로 사용하면 변수 타입 사이즈에 맞게 메모리를 할당하고
지역변수로 단독 사용을 할 경우 byte, short, int 모두 4byte 만큼 메모리를 할당한다.
그러니 두번 일 시키지 말고 정수는 int를 쓰자.
3. 배열 (array)
1. 일정한 차례나 간격에 따라 벌여 놓음. ex> 배열 순서 2. 컴퓨터 동일한 성격의 데이터를 관리하기 쉽도록 하나로 묶는 일. ex> 배열 변수를 선언하다. |
이번에 우리는 2번 뜻을 알아볼 것이다.
동일한 성격의 데이터라는 것이 무엇이며, 이것을 관리하기 쉽도록 묶었다는 것을 무엇일까?
문제는 이게 왜 필요하냐는 거다. 개념적으로 알아보자.
10개의 정수를 구분해서 기억해야 한다.
그래서 변수 10개를 선언하고 각 변수에 다음과 같이 값을 할당 했다.
int variable_1 = 100; int variable_2 = 200; int variable_3 = 300; ... int variable_10 = 1000; |
지금은 10개의 정수만 사용하기 때문에 복사 붙여넣기 몇 번으로 작성할 수 있다.
만약 기억해야 하는 정수가 100개라면 어떨까?
변수를 정수1 부터 정수100 까지 만들고 하나씩 값을 할당한다고 상상해보자.
열심히 복사하면 된다 하겠지만 관리할 수 있을까?
소스 길이도 엄청 길어지고 관리도 힘들고 또 n번째 정수가 수정되어야 한다면.. 재앙이다.
그래서 배열이 생겼다.
컴퓨터에서 배열이 이렇게 생기진 않았지만, 길이 n의 배열을 가시화 할 때 다음과 같이 표현 한다.
위의 숫자는 배열의 순서를 나타내는 숫자로 보통 '인덱스'라고 하며 0부터 (제로 베이스) 센다.
정수 10개를 배열에 담는다고 하면 다음과 같이 하면 된다.
int arrVariable[] = 길이 10의 int 배열 |
위와 같이 선언했을 때 다음과 같은 이미지를 떠올리면 된다.
100개가 필요하면 길이 10이 아닌 100인 int 배열을 선언하면 된다.
지금은 이렇게 묶음으로 관리하는게 얼마나 좋은지 와닿지 않을 수 있다.
하지만 반복문을 만나고 알고리즘 공부를 시작하면 배열 없는 세상은 상상할 수 없을거다.
적당한 예시가 떠오르지 않아 이정도밖에 전달하지 못하고 있지만
추후에 처음 보는 사람도 쉽게 이해할만한 예시가 떠오르면 내용을 추가하겠다.
4. 구조체 (struct)
사실 구조체를 언급하는건 반칙이다.
자바에는 구조체가 없기 때문이다. 그럼에도 불구하고 왜 굳이 구조체를 넣었을까?
클래스라는 개념으로 가는 징검다리라고 생각했기 때문이다.
구조체는 C언어에 있는 개념이다.
앞서 배열에 대해 알아보았을 때, 동일한 성격의 데이터를(자료형) 관리하기 쉽도록 묶은 것이라고 했다.
사람들은 동일한 성격의 데이터만 묶은게 불만이었나보다.
동일하지 않은 성격을 가진 데이터들도 하나로 묶어 관리하고 싶었나본데,
그게 바로 구조체이다.
예를 들면 학교에서 학생들의 성적을 관리한다고 하자.
5과목의 점수를 score 라는 이름의 배열을 만들어 관리한다고 하면 다음과 같다.
학생1의 점수 score_1 [90, 80, 95, 80, 90]
학생2의 점수 score_2 [95, 85, 80, 90, 95]
학생3의 점수 score_3 [93, 82, 95, 80, 85]
score 라는 이름의 배열을 사용해서 훌륭하게 점수를 관리할 수 있게 되었는데, 혹시 공통된 부분이 있지 않은가?
언어를 만든 사람들을 포함해서 프로그램을 만드는 사람들은 보통 의미없이 중복해서 반복하는걸 싫어한다.
그래서 다음과 같이 묶으면 어떨까? 생각했다.
'학생' 이라는 구조체를 그림으로 나타내본 것이다.
학생들이 갖는 공통된 속성을 구조체라는 덩어리로 묶어 가지고 있다가
새로운 학생이 생기면 저 구조만 복사해다가 그 학생에 맞는 정보로 채워주면 된다.
구조체의 장점은 배열과 달리 서로 다른 성격의 데이터들도 묶었다는 것이다.
** 첨언을 하자면 C언에어는 클래스 개념이 없다. 그래서 그런건 아니지만, 구조체도 자바에서의 클래스 처럼 어디선가 가져다가 사용을 해야한다. 다시 말해서 선언만 가지고는 쓸모가 없다. 자바에서 클래스가 의미를 갖기 위해 객체화 (실체화) 한다고 말했었다. 이와 같이 구조체 역시 프로그램 내에서 정의된 구조체를 가져다 써야 의미를 가질 수 있다. 더 중요한 얘기가 있는데, 그건 클래스 설명 말미에 추가하겠다. |
5. 클래스 (class)
앞서 살펴본 구조체의 업그레이드 버전(?)이 바로 클래스이다.
즉, 구조체를 포함하여 더 큰 개념이 자바에서 클래스라고 할 수 있다.
클래스에 포함되는 내용은 크게 두가지로 구분할 수 있다.
첫번째가 속성, 두번째가 행위이다.
앞서 학생을 예시로 들었으니 그 내용을 활용하여 알아보자.
첫번째로 속성에 대해 알아보자.
보통 명사로 표현할 수 있는 것들을 속성이라고 할 수 있다.
구조체에서 작성한 이름과 점수라는 것은 그 학생이 갖는 속성이다.
조금 더 추가하자면 나이, 성별, 취미, 특기 등 이러한 것을 속성으로 가질 수 있다.
두번째로 행위에 대해 알아보자.
보통 동사로 표현할 수 있는 것들을 행위라고 할 수 있다.
학생이 할 수 있는 행위에는 무엇이 있을까?
등교하다. 하교하다. 점심먹다. 등 정말 많이 있다.
클래스는 이것을 하나로 묶을 수 있다.
얼마나 매력적인가.
속성과 행위 모두를 반드시 포함해야할 필요는 없다.
선택적으로 필요한 내용만 추가하면 된다.
지금까지 말한 내용을 바탕으로 학생 클래스를 만들면 다음과 같이 그려볼 수 있다.
자바에서 속성에 해당하는 내용을 보통 멤버 필드 라고 하고, 행위를 멤버 메소드 라고 한다.
혹시 기억할지 모르겠지만, 클래스는 개념적으로 설계도라고 할 수 있다고 했다.
위에 그림으로 표현한 '학생'이라는 클래스를 보면 다음과 같은 생각을 할 수 있다.
학생은 이름, 나이, 성별, 취미, 특기, 점수를 가지고 있고
등교하다, 하교하다, 점심먹다를 할 수 있구나.
이 사실을 바탕으로 이 클래스는 무엇을 하는 것인지 또 이것을 가지고 내가 어떤 행위를 할 수 있는지 머릿속으로 그려볼 수 있다.
자료의 형태를 내 마음대로 구성할 수 있다니. 매력적이지 않은가.
자, 그러면 여기서 가장 중요한 얘기 하나가 남았다.
지금까지 다양한 종류의 자료형을 살펴봤다.
그 중에서 정수 타입의 자료형 int를 떠올려 보자.
4byte 크기의 정수값을 갖는 자료형이라는 것을 알 수 있다.
앞서 살펴본 학생 클래스도 똑같이 대입해보자.
멤버 필드로 이름, 나이, 성별, 취미, 특기, 점수를 가지며
등교하다, 하교하다, 점심먹다의 행위(= 기능)를 할 수 있는 자료형이라는 것을 알 수 있다.
하고싶은 얘기는 클래스도 자료형이다.
그것도 사용자가 정의한 자료형.
나중에 공부를 하다보면 본질이 무엇인지 혼란스러울 때가 올지 모르겠다.
그럴때 이것만은 잊지 말자.
1. 클래스도 자료형이고 사용자가 정의했을 뿐이다.
2. 모든 변수의 선언은 다음과 같이 한다.
[데이터 타입(자료형)] [변수명] = [변수에 넣을 값]
최대한 소스를 작성하지 않고 개념적인 부분만을 전달해보려 했는데, 잘 됐는지 모르겠다.
'프로그래밍 언어 > 나 혼자 떠드는 자바' 카테고리의 다른 글
나 혼자 떠드는 자바 : 자바 실행 환경 (즐거운 메모장 코딩 1편) (0) | 2021.05.01 |
---|---|
나 혼자 떠드는 자바 : 자바 실행 환경 (자바 설치 방법) (0) | 2021.05.01 |
나 혼자 떠드는 자바 : 자바 언어가 가지는 특징 '배워본 언어가 없는데 어떻게 비교를 해' (0) | 2021.05.01 |
나 혼자 떠드는 자바 : 프로그래밍 언어란 (0) | 2021.05.01 |
나 혼자 떠드는 자바 : 내용구성 (0) | 2021.05.01 |