[Java] 변수 (Variable)
▶ 들어가기 전에
우리가 프로그래밍을 할 때 변수는 필수적으로 사용되는 요소이다. 하지만 변수에 대해 자세하게 알지 못하고 사용하게 되면 메모리 누수, 스택 오버플로우 문제로 이어질 수 있는 위험도 존재한다.
그래서 변수에 대한 정리를 해야겠다는 생각이 들어 포스팅을 하게 되었다.
▶ 변수란?
변수란 다음과 같이 정의된다.
단 하나의 값을 저장할 수 있는 메모리 공간
하나의 변수에는 하나의 값만 저장할 수 있으며, 새로운 값 저장시 기존 값은 사라진다.
변수는 선언과 동시에 초기화(Initialization) 해야 한다.메모리는 공유자원이므로 전에 다른 프로그램에 의해 저장된 쓰레기 값(Garbage Value)이 남아있을 수 있기 때문이다.
변수의 명명규칙
"변수의 이름" 처럼 프로그래밍에서 사용하는 모든 이름을 식별자 라고 한다.
식별자는 같은 영역 내에서 서로 구분될 수 있어야하므로 다음과 같이 5가지 규칙이 존재한다.
- 대소문자가 구분되며 길이에 제한이 없음.
- 예약어를 사용해서는 안됨.
- 숫자로 시작하면 안됨.
- 특수문자는 '_'와 '$' 만을 허용함.
자바 프로그래머들에게 권장되는 규칙(Coding Convension)도 존재한다.
- 클래스 이름의 첫 글자는 항상 대문자로 한다.
- 여러 단어로 이루어진 이름은 단어의 첫 글자를 대문자로 한다. (카멜 표기법)
- 상수(const)의 이름은 모두 대문자로 한다. 여러 단어로 이루어진 경우 '_'로 구분한다.
▶ 변수의 타입
변수에 저장되는 값의 종류에 따라 저장될 공간의 크기와 저장형식을 정의한 것이 자료형(data type)이다.
자료형은 크게 기본형과 참조형으로 나눠진다.
기본형
기본형 변수는 실제 값(data)을 저장한다.
논리형 | boolean (1 byte) |
true, false 중 하나를 값으로 갖는다. 조건식과 논리적 계산에 사용됨. | |
문자형 | char (2 byte) |
문자를 저장하는데 사용. 하나의 문자만 저장. | |
정수형 | byte (1 byte), short (2 byte), int (4 byte), long (8 byte) |
정수를 저장하는데 사용되며, 기본으로 int를 사용. byte는 이진 데이터를 다룰 때 사용되며, short는 C언어와의 호환을 위해 추가됨. | |
실수형 | float (4 byte), double (8 byte) |
실수를 저장하는데 사용. 주로 double을 사용. |
- boolean은 true, false만 존재하므로 가장 작은 크기인 1 byte
- char는 자바에서 유니코드를 사용하므로 2 byte
- byte는 크기가 1 byte라서 byte
- int(4 byte)를 기준으로 짧아서 short (2 byte), 길어서 long (8 byte)
- float는 실수 값을 부동소수점 방식으로 저장하기 때문에 float
- double은 float보다 두 배의 크기를 가지므로 double
1. 논리형
boolean 자료형은 디폴트 값이 false이다. 주로 논리구현에 사용되며, 값이 true, false 두가지 뿐이기 때문에 1 bit만으로도 충분하지만, 자바에서는 기본 단위가 byte이므로 boolean 자료형의 크기는 1 byte이다.
2. 문자형
char 자료형은 문자를 저장하는 듯 하지만, 해당 문자의 유니코드(정수)가 저장된다. 예를 들면 'A'를 저장하게 되면, 'A'의 유니코드인 65가 char형 변수에 저장된다.
char 자료형의 크기는 2 byte이므로, 이진수로 표현할 수 있는 정수의 개수인 65536개의 코드를 사용할 수 있다.
예를 들어, 문자 'A'가 저장되면, 2진수 '0000000001000001'(10진수로 65, 16비트이므로 16자리)로 저장된다.
인코딩과 디코딩(encoding & decoding)
문자가 저장될 때 유니코드로 인코딩 하여 정수로 저장하며, 저장된 문자를 읽어올 때는 유니코드를 디코딩하여 문자로 되돌려서 보여주게 된다.
이와 같이 인코딩을 어떤 코드로 했는지가 중요하다.
간혹 html문서의 글자가 깨져서 알아볼 수 없는 값이 나타날 때가 있는데, 이는 html의 인코딩에 사용된 코드표와 브라우저에 설정된 디코딩 코드표가 맞지 않아서이다.
아스키(ASCII)
아스키는 128개의 문자 집합을 제공하는 7 bit 부호이다. 나는 주로 알파벳 및 기호의 유니코드를 확인할 때 아스키 코드 표를 보고 매칭되는 정수를 확인하곤 했다.
확장 아스키(Extended ASCII)
일반적으로 데이터는 byte단위로 다뤄지는데 아스키는 7 bit이므로 1 bit가 남는다. 이 남는 공간을 활용해 문자를 추가로 정의한 것이 '확장 아스키' 이다.
확장 아스키로 표현할 수 있는 문자의 개수가 255개인데, 이는 한글을 표현하기에는 부족한 숫자다. 그래서 두 개의 문자 코드로 한글을 표현하는 방법이 나오게 되었다.
한글을 표현하는 방법에는 조합형과 완성형이 있다.
조합형은 초성, 중성, 종성을 조합하는 방식인데, 현재 사용되지 않는다.
완성형은 확장 아스키의 일부 영역(162~254)에 해당하는 두 문자코드를 조합하여 한글을 표현한다.
'완성형(KSC 5601)'에 없는 잘 안 쓰이는 8822글자를 추가한 것이 '확장 완성형(CP 949)'. 이것은 한글 윈도우에서 사용하는 문자 인코딩이다.
코드 페이지(code page, cp)
IBM은 PC를 사용하는 지역이나 국가에 따라 여러 버전의 '확장 아스키'가 필요하였다. 이를 '코드 페이지'라 하고, 각 코드 페이지에 'CP xxx)'와 같은 형식으로 이름을 붙였다.
한글 윈도우는 'CP 949', 영문 윈도우는 'CP 437'을 사용한다.
유니코드(Unicode)
서로 다른 지역, 다른 언어의 사용자들이 공통적으로 사용할 수 있는 문자 집합이 필요하였고, 그로 인해 유니코드가 나오게 되었다.
유니코드 인코딩에는 UTF-8, UTF-16, UTF-32 등 여러 종류가 있다. 자바에서는 UTF-16을 사용한다.
UTF-8은 모든 문자를 1~4 byte의 가변 크기로 표현한다.
UFT-16은 모든 문자를 2 byte의 고정 크기로 표현한다.
모든 문자가 2 byte로 크기가 동일한 UTF-16이 문자를 다루기엔 편리하지만, 영어와 숫자가 1 byte를 차지하는데 굳이 2 byte로 표현되어 문서의 크기가 커진다는 단점이 있다.
UTF-8은 문자의 크기가 가변적이므로 사용하기엔 어렵지만 UTF-16에 비해 크기가 작다. 인터넷에서는 전송 속도가 중요하므로 문서의 크기가 작을 수록 유리하다.
참조형
참조형 변수는 어떤 값이 저장되어 있는 메모리 주소를 값으로 저장한다.
(Java는 C언어와 달리 참조형 변수간의 연산이 불가능하므로 실제 연산에 사용되는 것은 모두 기본형 변수)
상수와 리터럴 (Constant & Literal)
상수(Constant)는 값 저장 후 다른 값으로 변경이 불가능하다.
선언시에 변수의 타입 앞에 최종이라는 의미의 키워드 'final'을 붙여주면 된다.
final int MAX_SPEED = 10;
상수는 위와 같이 반드시 선언과 동시에 초기화해야 하며, 그 후 변경이 허용되지 않는다.
보통 상수는 static으로 선언하여 스레드간 공용 데이터로 사용한다.
리터럴(Literal)은 통상 값이라 부르는 것들이 상수의 의미인데 프로그래밍에서는 상수를 "값을 한 번 저장하면 변경할 수 없는 저장공간"으로 정의하였기 때문에 이와 구분하기 위해 값을 리터럴이라는 다른 이름으로 정의한 것이다.
'A'와 같이 하나의 문자는 작은 따옴표로 감싸야 하며 '문자 리터럴'이라 한다.
"AB"와 같이 두 문자 이상은 큰 따옴표로 감싸야 하며 '문자열 리터럴'이라 한다.
문자 리터럴
- char 타입
- 안에 아무런 문자도 넣지 않는 빈 값을 허용하지 않는다.
문자열 리터럴
- String 타입
- 빈 값으로 저장하는 것이 가능하다.
- 덧셈 연산이 가능한데, 왼쪽에서 오른쪽의 방향으로 연산을 수행하기 때문에 순서에 따라 결과가 달라진다.
10 + 10 + "" = "20"
"" + 10 + 10 = "1010"
▶ 진법
10진법과 2진법
일상 생활에서 주로 사용하는 것은 10진법이다. 컴퓨터의 경우 0과 1만으로 구성된 2진법을 사용한다.
2진법은 10진법에 비해 많은 자리수를 필요로 한다.
2진수 | 10진수 |
0 | 0 |
1 | 1 |
10 | 2 |
11 | 3 |
100 | 4 |
101 | 5 |
110 | 6 |
111 | 7 |
1000 | 8 |
1001 | 9 |
1010 | 10 |
8진법과 16진법
8진수는 2진수 3자리를, 16진수는 2진수 4자리를 각각 한자리로 표현할 수 있다.
8진수는 0~7, 16진수는 0~9, A~F로 표현한다.
2진수를 8진수로 변환할 때는 2진수 끝에서부터 3자리씩 끊어서 그에 해당하는 8진수로 변환하면 된다.
2진수를 16진수로 변환할 때는 2진수 끝에서부터 4자리씩 끊어서 그에 해당하는 16진수로 변환하면 된다.
비트 (bit)와 바이트 (byte)
1비트는 컴퓨터가 값을 저장하는 최소 단위이다.
1비트는 너무 작은 단위라 1비트 8개를 묶어서 1바이트로 정의하여 데이터의 기본 단위로 사용한다.
워드(word)는 'CPU가 한 번에 처리할 수 있는 데이터의 크기'를 의미한다.
워드는 CPU가 몇 비트 운영체제인지에 따라 달라진다.
32비트 CPU에서는 32비트 (4바이트), 64비트 CPU에서는 64비트(8바이트)이다.
CPU 32비트, 64비트는 CPU가 데이터를 처리할 때 사용하는 ‘레지스터’의 크기를 말한다.
레지스터는 극히 소량의 데이터나 처리 중인 중간 결과를 일시적으로 기억해 두는 고속의 전용 영역을 말한다.
32비트보다 64비트가 속도가 빠르고 많은 메모리 사용이 가능하다.
▶ 형변환(캐스팅, casting)
변수 또는 상수의 타입을 다른 타입으로 변환하는 것
형변환 방법은 간단하다. 형변환 대상 변수나 리터럴 앞에 변환하고자 하는 타입을 괄호화 함께 붙여준다.
명령어 (타입) 피연산자로 사용할 수 있다.
기본형과 참조형 간의 형변환은 불가능하다.
크기가 작은 자료형에서 큰 자료형으로 형변환 시엔 손실되는 데이터가 없지만, 크기가 큰 자료형에서 작은 자료형으로 형변환 시엔 '값 손실'이 발생할 수 있다.
'BackEnd > Java' 카테고리의 다른 글
[Java] 배열 (0) | 2022.06.19 |
---|---|
[Java] 조건문과 반복문 (0) | 2022.06.11 |
[Java] 연산자 (0) | 2022.06.06 |
[Java] JVM (0) | 2022.04.30 |
[Java] Java란? (0) | 2022.04.30 |