archive
[Java] 변수와 자료형 본문
- 변수
단 하나의 값을 저장할 수 있는 메모리 공간
→ 새로운 값을 저장하면 기존의 값은 사라진다.
- 변수의 선언
변수타입 변수이름;
(ex) int age;
변수 선언을 통해 메모리의 빈 공간에 변수타입에 알맞은 크기의 저장공간이 확보되고, 이 공간은 변수이름을 통해서 사용할 수 있게 된다.
- 변수의 초기화
변수를 사용하기 전에 처음으로 값을 저장하는 것. 쓰레기값 제거를 위해 반드시 초기화 후 사용해야한다. 대입연산자 '=' 을 이용
(ex) int age = 25; // age를 선언하면서 25로 초기화
→ int age; age=25; 와 같음
- 자료형
값의 종류에 따라 값이 저장될 공간의 크기와 저장형식을 정의한 것
- 기본형과 참조형
기본형 : 실제 값을 저장한다. (ex) boolean, char, byte, short, int, long, float, double
참조형 : 객체의 주소를 저장한다. (ex) 8개의 기본형을 제외한 모든 타입
→ 참조형 변수를 선언할 때는 변수의 타입으로 클래스 이름을 사용하므로, 클래스의 이름이 곧 참조변수의 타입이 된다.
(변수 타입이 기본형이 아닌 것은 모두 참조형 변수이다.)
- 기본형
논리형 : boolean
문자형 : char
정수형 : byte, short, int, long
실수형 : float, double
- 상수
변수와 마찬가지로 값을 저장할 수 있는 공간이지만, 한 번 저장하면 값을 변경할 수 없다. final 키워드로 선언한다.
(ex) final int MAX = 100; // 반드시 선언과 동시에 초기화해줘야 한다.
관례적으로 상수의 이름은 모두 대문자로 정한다.
-리터럴
일상생활에서의 상수의 의미와 같다. 즉, 값 자체를 의미한다.
(ex) final int MAX = 100; // 상수 : MAX, 리터럴 : 100
char c = 'a'; // 변수 : c, 리터럴 : 'a'
- 논리형 : boolean
true/false 중 하나의 값을 가짐 (기본형은 false)
(ex) boolean checked = false;
- 문자형 : char
단 하나의 문자만을 저장할 수 있다.
(ex) char ch = 'A';
변수 ch에는 A에 대한 유니코드, 즉 65가 저장된다. 따라서 char ch = 65; 로 선언해도 같은 결과를 얻을 수 있다.
- 정수형 : byte, short, int, long
byte(1) < short(2) < int(4) < long(8) 단위 : byte
(ex) int age = 25;
변수에 어떤 진법의 리터럴을 저장해도 실제로는 2진수로 바뀌어서 저장된다.
정수형은 1개의 sign bit(부호 비트)와 n-1개의 magnitude bit(절대값 크기)를 갖는 형식으로 저장된다.
따라서 -2^n-1 ~ 2^n-1 - 1 범위의 수를 표현할 수 있다.
(ex) int형(32bit) : -2^32 ~ 2^32 - 1
(참고)
JVM의 피연산자 스택(operand stack)이 피연산자를 4byte단위로 저장하기 때문에,
byte, short의 값을 계산할 때는 4byte로 변환하여 연산이 수행된다.
따라서 오히려 int가 더 효율적이다.
결론적으로 정수형 변수를 선언할 때는 대부분의 경우에는 int를 사용하고, 범위를 초과하면 long을 사용하며, 시간보다 공간의 절약이 필요한 경우에 byte, short을 사용하는 것이 좋다.
- 오버플로우
해당 타입이 표현할 수 있는 값의 범위를 넘어가는 것.
에러가 발생하지는 않지만 원하는 값과 다른 결과가 나온다.
범위의 최대값 이상/최소값 이하로는 표현할 수 없다.
따라서 최대값 + 1 = 최소값 / 최소값 - 1 = 최대값 이 되기 때문에 올바른 결과를 얻을 수 없다. (1111+0001 = 0000, ∵ 최상위 비트 짤림)
- 실수형 : float, double
float(32) < double(64) 단위 : byte
실수형은 값의 크기와 더불어 얼마나 0에 가깝게 표현할 수 있는지(정밀도)도 중요하다.
실수형은 정수형과 값을 저장하는 방식이 다르다. 부동소수점 방식을 사용한다.
(ex) flaot형
sign bit : 1 bit (부호 저장)
exponent bit : 8bit (지수에 127을 더해서 저장)
manitissa bit : 23bit (가수를 저장, 이 때 맨 앞의 1은 저장하지 않음)
즉, (-1)^S * (1.M)* 2^E-127 의 지수형태로 나타낼 수 있어서, 큰 범위의 값을 저장할 수 있다.
float형은 7자리 정도의 정밀도를 가진다.
연산 속도의 향상과 메모리 절약을 위해서는 float을, 더 높은 정밀도를 표현하기 위해서는 double형을 사용해야 한다.
(주의) 같은 값을 저장해도 정밀도때문에 서로 다른 값이 저장될 수 있으며,
저장할 때 이미 값이 달라졌기 때문에 형변환을 해도 같아지지 않는다.
- 형변환(Casting)
변수 또는 상수의 타입을 다른 타입으로 변환하는 것
(타입)피연산자 와 같은 방식으로 사용한다.
(ex) double d = 85.4; int score = (int)d; // score=85 저장됨
boolean을 제외한 나머지 타입들은 서로 형변환이 가능하며,
기본형과 참조형간의 형변환은 불가능하다.
(1) 정수형 간의 형변환
byte -> int 형변환은 작은 타입에서 큰 타입으로의 변화이므로 빈 공간에 0또는 1이 채워진다. 따라서 값 손실이 일어나지 않는다.
float -> int 형변환은 큰 타입에서 작은 타입으로의 변화이므로 크기 차이만큼 잘려 나간다. 따라서 값 손실이 일어날 수 있다.
(2) 실수형 간의 형변환
float->double형변환은 빈 공간을 0으로 채운다.
double->float형변환은 23자리만 남기고 남는 크기는 버려진다. 이 때, 마지막(24)번째 자리가 1이였으면 반올림이 발생해 23번째자리의 값이 1 증가한다.
float타입의 범위를 넘는 값을 float으로 형변환하는 경우에는 무한대 or 0을 결과로 얻는다.
(3) 정수형과 실수형 간의 형변환
정수 -> 실수 형변환은 비교적 간단하다. 정수를 2진수로 변환 후 정규화해서 저장형식에 맞게 저장하면 된다. 이 때, 만약 8자리 이상의 정수를 실수로 변환할 때에는 double을 사용해야 오차가 발생하지 않는다.
실수-> 소수 형변환은 실수형의 소수점 이하 값은 버려진다. (반올림X, 버림O) 버림한 수가 정수의 저장 가능 범위를 초과하면 오버플로우가 난다.
(참고) printf함수에서 10진수를 2진수로 변환하여 출력해주는 지시자는 없기 때문에,
Integer.toBinaryString(int i)를 사용해야 한다. 정수를 2진수로 변환해 문자열로 반환하므로 %s를 사용한다.
(참고) C언어와 달리 char형을 %d 지시자로 출력할 수 없다. 따라서 int형으로 형변환 후에 %d를 이용해 출력해줘야 한다.
- 자동 형변환
서로 다른 타입간에 연산을 할 때, 타입을 일치시키는 것이 원칙이나 편의상 생략할 수 있다. 이때 컴파일러가 생략된 형변환을 자동으로 추가한다.
(ex) float f = 1234; // float f = (float)1234;
위와 같이 범위 이내의 값을 저장할 때에는 형변환을 생략해도 문제 없다.
아래와 같이 범위 바깥의 값을 저장하는 경우엔 명시적으로 형변환을 해줘야 한다.
byte b = 1000; // possibly lossy conversion from int to byte 라는 에러가 뜬다.
char c = (char)1000; // 명시적으로 형변환을 하는 경우에는 의도된 형변환으로 간주하여 에러가 발생하지 않는다.
연산식에서도 형변환이 자주 생략된다.
(ex) int i = 3; double d = 1.0 + i; // double d = 1.0 + (double)i;
서로 다른 두 타입간의 형변환에서는 둘 중 범위가 넓은 타입으로 형변환된다. 이를 '산술변환'이라고 한다.
컴파일러는 최대한 기존의 값을 보존할 수 있는 타입으로 자동 형변환한다.
즉, 값의 범위가 작은 쪽에서 큰 쪽으로 가는 방향으로의 형변환은 형변환 연산자를 생략하여도 자동 형변환이 되며,
그 반대 방향으로의 변환은 반드시 형변환 연산자를 써줘야 한다.
'STUDY > Java' 카테고리의 다른 글
[OOP] Chap3. 자바와 객체지향 (0) | 2021.02.01 |
---|---|
[OOP] Chap2. 자바와 절차적/구조적 프로그래밍 (0) | 2021.01.27 |
Java 애플리케이션 작동 원리 (0) | 2021.01.07 |
Java 개발환경구축 / Java API문서 (0) | 2021.01.07 |
Java란 / JVM (0) | 2021.01.07 |