1. 변수 (variable)
“값”을 잘 다루는 것은 중요한 프로그래밍 능력 중 하나.
1.1 변수(variable)란?
단 하나의 값을 저장할 수 있는 메모리 공간
- 이 공간에 저장된 값이 변경될 수 있기 때문에 ‘변수’라는 이름을 사용
1.2 변수의 선언과 초기화
변수의 선언
int age;
- 변수타입
int
- 변수에 저장될 값이 어떤 타입인지 지정하는 것.
- 자바에는 정수형, 실수형, 문자형 등 타입을 제공
- 변수이름
age
- 변수에 붙인 이름
- 메모리 공간에 이름을 붙여주는 것.
- 그 이름을 이용해 저장공간에 값을 저장하고, 저장된 값을 읽어오기도 할 수 있다.
- 같은 이름의 변수가 여러개 존재하면 안된다.
- 변수를 선언하면 메모리의 빈 공간에
변수타입에 맞는 크기의 저장 공간이 확보되고, 앞으로 이저장공간을 변수이름으로 사용할 수 있다.
변수의 초기화
변수를 사용하기 전에 처음으로 값을 저장하는 것
- 변수를 선언한 이후부터는 변수를 사용할 수 있으나, 그 전에 반드시 변수를
초기화(initiaization)해야한다.
- 메모리는 여러 프로그램이 공유하는 자원이므로 전에 다른 프로그램에 의해 저장된 알 수 없는 값(쓰레기값, garbage value)가 남아있을 수 있다.
- 대입연산자
=를 이용해 변수에 값을 저장한다.
- 변수의 종류에 따라 변수의 초기화를 생략할 수 있는 경우도 있지만, 변수는 사용되기 전 적절한 값으로 초기화 하는 것이 좋다.
- 지역변수는 반드시 초기화를 해야함.
- 클래스변수와 인스턴스 변수는 초기화를 생략할 수 있다.
- 변수에 저장된 값을 사용하려면 변수의 이름만 적어주면 된다.
- 변수에 값을 저장하는
대입연산(=)은 우변의 모든 계산이 끝난 후에 제일 마지막에 수행된다.
두 변수의 값 교환하기
1.3 변수의 명명규칙
식별자 (Identifier)
- 프로그래밍에서 사용하는 모든 이름
- 같은 영역 내에서 서로 구분(식별)될 수 있어야한다.
- 식별자 생성 규칙
- 대소문자가 구분되며 길이에 제한이 없다.
- True와 true는 서로 다른 것으로 간주된다.
- 예약어를 사용해서는 안된다.
- true는 예약어이기 때문에 사용할 수 없지만, True는 가능
- 숫자로 시작해서는 안된다.
- top10은 허용, 7up은 허용되지 않는다.
- 특수문자는
_와 $만을 허용한다.
- $harp은 허용되지만 S#arp는 허용되지 않는다.
- 예약어는 키워드(keyword) 혹은 리저브드 워드(reserved word)라고 하는데, 프로그래밍의 구문에 사용되는 단어를 뜻한다.
- 클래스나 변수, 메서드의 이름으로 사용할 수 없다.
- 권장 규칙
- 클래스 이름의 첫 글자는 항상 대문자로 한다.
- 변수와 매서드의 이름의 첫 글자는 항상 소문자로 한다.
- 여러 단어로 이루어진 이름은 단어의 첫 글자를 대문자로 한다.
- 상수의 이름은 모두 대문자로 한다. 여러 단어로 이루어진 경우
_로 구분한다.
2. 변수의 타입
- 우리가 주로 사용하는 값(data)의 종류(type)은 크게 ‘
문자’와 ‘숫자’로 나눌 수 있으며, 숫자는 다시 ‘정수’와 ‘실수’로 나눌 수 있다.
- 이러한 값의 종류에 따라 값이 저장될 공간의 크기와 저장 형식을 정의한 것이 자료형(data type)이다.
- 자료형에는 문자형(char), 정수형(byte, short, int, long), 실수형(float, double) 등이 있으며, 변수를 선언할 때는 저장하려는 값의 특성을 고려하여 가장 알맞은 자료형을 변수의 타입으로 선택하면 된다.
기본형과 참조형
- 기본형 변수 (Primitive Type)
- 실제 값(data)를 저장
- 실제 연산에 사용되는 변수
- 종류
- 논리형 (boolean)
- 문자형 (char)
- 정수형 (byte, short, int, long)
- 실수형 (float, double)
- 참조형 변수 (Reference Type)
- 어떤 값이 저장되어 있는 주소(memory address)를 값으로 갖는다.
- 자바는 참조형 변수간 연산을 지원하지 않음.
- 8개의 기본형을 제외한 나머지 타입
- 참조형 변수를 선언할 때는 변수의 타입으로 클래스의 이름을 사용하므로 클래스의 이름이 참조변수의 타입이 된다.
- 새로운 클래스를 작성하는 것 == 새로운 참조형을 추가하는 것
- 선언 방법
클래스이름 변수이름;
- 예시) Date 클래스 타입 참조변수 today 선언
Date today = new Date(); // Date 객체를 생성해서, 그 주소를 today에 저장
- 객체를 생성하는 연산자 new의 결과로 객체의 주소가 생성됨.
- 메모리에는 1byte 단위로 메모리 주소가 있다. 객체의 주소는 객체가 저장된 메모리 주소를 뜻한다.
- 참조형 변수는 null 또는 객체의 주소(4byt, 0x0 ~ 0xFFFFFFFF)를 값으로 갖는다.
- null은 어떤 객체의 주소도 저장되어 있지 않음을 뜻한다.
- 단, JVM이 64bit라면 참조형 변수의 크기는 8byte가 된다.
자료형(date type)과 타입(type)의 차이
- 기본형은 저장할 값(date)의 종류에 따라 구분되므로 기본형의 종류를 얘기할 때는
자료형(date type)이라는 용어를 쓴다.
- 하지만 참조형은 항상 객체의 주소(4byte 정수)를 저장하므로 값(data)이 아닌 객체의 종류에 의해 구분되므로 참조형 변수의 종류를 구분할 때는
타입(type)이라는 용어를 사용함.
타입(type)이 자료형(data type)을 포함하는 보다 넓은 의미의 용어.
2.1 기본형(Primitive type)
| 분류 | 타입 | 설명 |
|---|
| 논리형 | boolean | true와 false 중 하나를 값으로 가지며, 조건식과 논리적 계산에 사용된다. |
| 문자형 | char | 문자를 저장하는데 사용되며, 변수에 하나의 문자만 저장할 수 있다. |
| 정수형 | byte, short, int, long | 정수를 저장하는데 사용되며, 주로 int가 사용된다. byte는 이진 데이터를 다룰 때 사용되며, short는 C언어와의 호환을 위해 추가되었다. |
| 실수형 | float, double | 실수를 저장하는데 사용되며, 주로 double이 사용된다. |
- 문자형인 char는 문자를 내부적으로 정수(유니코드)로 저장하기 때문에 정수형과 별반 다르지 않음.
- boolean은 다른 기본형과의 연산이 불가능하다.
- int가 CPU가 가장 효율적으로 처리할 수 있는 타입이기 때문에 정수형 중 가장 보편적으로 사용.
- 효율적인 실행보다 메모리를 절약하고 싶다면 byte나 short를 선택.
- 정수형은 int, 실수형은 double이 기본 자료형이다.
- 기본형의 종류와 크기
| 1byte | 2byte | 4byte | 8byte |
|---|
| 논리형 | boolean | | | |
| 문자형 | | char | | |
| 정수형 | byte | short | int | long |
| 실수형 | | | float | double |
- 기본형의 크기와 범위
| 자료형 | 저장가능한 값의 범위 | 크기(bit) | 크기(byte) |
|---|
| boolean | false, true | 8 | 1 |
| char | '\u0000’ ~ ‘uffff’ | 16 | 2 |
| byte | -128 ~ 127 (-2^7 ~ 2^7 - 1) | 8 | 1 |
| short | -32768 ~ 23767 (-2^15 ~ 2^15 - 1 | 16 | 2 |
| int | -2_147_493_648 ~ 2_147_483_647(약 20억) | 32 | 4 |
| long | -2^63 ~ 2^63 - 1 | 64 | 8 |
| float | 1.4E-45 ~ 3.4E38 (1.410^-45 ~ 3.4 10^38 | 32 | 4 |
| double | 4.910^0324 ~ 1.8 10^308 | 64 | 8 |
- 실수형과 정수형의 저장형식은 다르다.
- 더 큰 값을 표현할 수 있으나 오차가 발생할 수 있다.
- float의 정밀도는 7자리
- double의 정밀도는 15자리
- float는 접미사나 정밀도 등 신경쓸 것이 많다. 이런 것들이 귀찮다면 그냥 double을 이용하자.
2.2 상수와 리터럴 (constant & literal)
상수(constant)
- 값을 저장할 수 있는 공간이지만 변수와 달리 한번 값을 지정하면 다른 값으로 변경할 수 없다.
- 변수의 타입 앞에
final을 붙여준다.
- 상수는 반드시 선언과 동시에 초기화해야 하며, 그 후부터는 상수의 값을 변경하는 것이 허용되지 않는다.
리터럴(literal)
- 상수를 값을 한 번 저장하면 변경할 수 없는 저장공간으로 정의하였기 때문에 이와 구분하기 위해 상수(를 다른 이름으로 불러야 한다.
- 변수: 하나의 값을 저장하기 위한 공간
- 상수: 값을 한번만 저장할 수 있는 공간
- 리터럴: 그 자체로 값을 의미
상수가 필요한 이유
- 리터럴을 사용하면 될텐데, 왜 굳이 상수를 사용하는가?
- 상수는 리터럴에 의미있는 이름을 붙여서 코드의 이해와 수정을 쉽게 만든다.
리터럴의 타입과 접미사
- 리터럴에도 타입이 있다.
- 변수의 타입은 저장될 값의 타입(리터럴의 타입)에 의해 결정되므로, 만일 리터럴에 타입이 없다면 변수의 타입도 필요없을 것이다.
- 정수형과 실수형에는 여러 타입이 존재하므로 리터럴에 접미사를 붙여 타입을 구분한다.
- long: I / L
- int: 접미사 없음.
- 16진수: 0x / 0X
- 8진수: 0
- JDK1.7부터 정수형 리터럴의 중간에 구분자
_를 넣을 수 있게 되어 큰 숫자를 편하게 읽을 수 있다.
- 실수형 리터럴에는 접미사를 붙여 타입을 구분한다.
- float: f
- double: d
- double이 기본형이기 때문에 접미사 생략 가능
- 접미사는 대/소문자를 구분하지 않으나 long의 경우 구분의 편의를 위해 L을 사용하는 편.
- p를 이용해서 실수 리터럴을 16진 지수형태로 표현할수 있다.
- p는 2의 제곱을 의미하며, p의 왼쪽에 16진수를 적고, 오른쪽에는 지수를 10진 정수로 적는다.
0x1p1 = (1 x 16^0) x 2^1
타입의 불일치
- 리터럴의 타입과 저장될 변수의 타입이 일치하는 것이 보통.
- 하지만 타입이 달라도 저장 범위가 넓은 타입에 좁은 타입의 값을 저장하는 것은 허용된다.
- 리터럴의 값이 변수 타입의 범위를 넘어서가나, 리터럴의 타입이 변수의 타입보다 저장범위가 넓으면 컴파일 에러가 발생한다.
- 각 타입의 저장범위를 안다면 판단가능한 내용이다.
문자 리터럴과 문자열 리터럴
- ‘A’와 같이 작은따옴표로 문자 하나를 감싼 것을
문자 리터럴이라고 한다.
- 두 문자 이상은 큰 따옴표로 감싸야 하며
문자열 리터럴이라고 한다.
- 문자열은 문자의 연속된 나열이라는 뜻이며, 영어로 string이라 한다.
- char타입의 변수는 단 하나의 문자만 저장할 수 있으므로 여러 문자(열)을 저장하기 위해서는 String 타입을 사용해야 한다.
- 문자열 리터럴은 안에 아무런 문자도 넣지 않는 것(””)을 허용하며, 이를 빈 문자열(empty String)이라고 한다.
- 그러나 문자 리터럴은 반드시 ‘’ 안에 하나의 문자가 있어야 한다.
- 원래 String은 클래스이므로 객체를 생성하는 연산자 new를 사용해야 하지만 특별히 new 없이 선언할 수도 있다.
- 덧셈 연산자를 이용해 문자열을 결합할 수 있다.
String name = "Ja" + "va"; // name = java
- 덧셈 연산자는 피연산자가 모두 숫자일 때는 두 수를 더하지만, 피연산자 중 어느 한 쪽이 String이면 나머지 한 쪽을 먼저 String으로 변환한 다음 두 String을 결합한다.
- 따로 toString()을 안해도 되는구나?!
- 덧셈 연산자는 왼쪽에서 오른쪽의 방향으로 연산을 수행하기 때문에 결합순서에 따라 결과가 달라진다.
- 기본형 타입의 값을 문자열로 변환할 때는 아무 내용도 없는 빈 문자열(””)을 더해주면 된다.
2.3 형식화된 출력 - printf()
- 지시자(specifier)를 통해 변수의 값을 여러 가지 형식으로 변환하여 출력하는 기능을 가지고 있다.
- 지시자는 값을 어떻게 출력할 것인지르 ㄹ지정해주는 역할을 한다.
- 출력할 값과 지시자의 순서 및 개수가 일치해야 한다.
print()는 출력 후 줄바꿈을 하지 않는다. 줄바꿈을 위해 지시자 %n을 따로 넣어줘야 한다.
- 자주 사용되는 printf()의 지시자
| 지시자 | 설명 |
|---|
| %b | boolean 형식으로 출력 |
| %d | 10진 형식으로 출력 |
| %nd | n자리 정수로 출력 (앞에 space) |
| %-nd | n자리 정수로 출력하되, 빈 자리는 뒤에 출력 |
| %0nd | n자리 정수로 출력하되, 빈 자리에 0 출력 |
| %o | 8진 형식으로 출력 |
| %x, %X | 16진 형식으로 출력 |
| %f | 부동 소수점 형식으로 출력 |
| %e, %E | 지수 표현식의 형식으로 출력 |
| %c | 문자로 출력 |
| %s | 문자열로 출력 |
- char 타입을
%d로 출력할 수 없다. int 타입으로 형변환 후 출력 가능
2.4 화면에서 입력받기 - Scanner
- JDK1.6에서 추가된 Console 클래스를 사용하는 것이 최신 방법
- 이클립스와 같은 IDE에서 잘 동작하지 않아 Scanner zmffotmfmf tkdyd
- nextInt()같은 녀석은 연속적으로 값을 받기 까다로우니 readLine()을 쓰라구?!
3. 진법
3.1 10진법과 2진법
- 컴퓨터는 2진법을 사용함.
- 10진수를 저장하면 2진수로 바뀌어 저장된다.
- 2진법은 10진법에 많은 자리수를 피룡로 한다.
3.2 비트(bit)와 바이트(byte)
- 비트(bit): 한 자리의 2진수
- 1비트는 컴퓨터가 값을 저장할 수 있는 최소단위
- 바이트(byte): 8자리의 bit 묶음
- 1비트는 너무 작은 단위이기에 비트 8개를 묶어 바이트라는 단위로 정의해 데이터의 기본 단위로 사용한다.
- 워드(word): CPU가 한 번에 처리할 수 있는 데이터의 크기(32bit CPU: 4byte / 64bit CPU: 8byte)
- nibble: 4bit. 16진수 1자리를 저장할 수 있는 단위
- n비트로 표현할 수 있는 10진수
- 값의 개수 : 2^n
- 값의 범위 : 0 ~ 2^n - 1
3.3 8진법과 16진법
- 2진법은 오직 0과 1 두개의 기호만으로 값을 표현하기 때문에 2진법으로 값을 표현하면 자리수가 상당히 길어지는 단점이 있다.
- 8진수는 2진수 3자리를, 16진수라면 4자리를 각각 한 자리로 표현할 수 있기 때문에 알아보기 쉽고 서로간의 변환 방법도 간단하다.
2진수를 8진수, 16진수로 변환
3.4 정수의 진법 변환
알고리즘… 했잖아요…?
10진수를 n진수로 변환
- 0보다 클 때까지 n으로 나누면서 나머지를 확인 후 반대로 읽음.
n진수를 10진수로 변환
실수의 진법 변환
10진 소수점수를 2진 소수점수로 변환
- 정수부는 3.4와 같이.
- 소수부는 반대로 2를 곱하면서 정수부를 아래로 적으면 됨.
2진 소수점수를 10진 소수점수로 변환
- 각 자리값는 그대로이므로 자리수 * 자리값의 합
3.6 음수의 2진 표현 - 2의 보수법
2의 보수법
- n의 보수는 더했을 때 n이 되는 수.
- 자리올림이 발생하고 0이 되는 수이기도 하다.
- 대부분의 시스템에서 2의 보수ㅜ법으로 부호있는 정수를 표현한다.
음수를 2진수로 표현하기
- 10진 음의 정수의 절대값을 2진수로 변환한다.
- 이 2진수의 2의 보수를 구한다.
2의 보수 구하기
- 2의 보수 = 1의 보수 + 1
- 1의 보수는 0을 1로, 1을 0으로 변환한 수
왜 2의 보수는 1의보수 + 1일까?
- 2의 진수의 1의 보수를 더하면 모든 자리가 1이 된다.
- 여기에 1을 더하면 모두 올림이 발생하며 2의 보수가 된다.
- 2진수의 특이점
4. 기본형(Primitive Type)
4.1 논리형 - boolean
- true / false 중 하나를 저장할 수 있다.
- 기본형은 false
- 논리 구현에 주로 사용된다.
- 1bit만으로 충분하지만, 자바에서는 데이터를 다루는 최소 단위가 byte이기 때문에 boolean의 크기가 1byte이다.
4.2 문자형 - char
- 문자를 저장하기 위한 변수를 선언할 떄 사용됨.
- char 타입의 변수는 단 하나의 무낮만을 저장할 수 있다.
- 문자의 유니코드(정수)가 저장된다.
- 문자 리터럴 대신 문자의 유니코드를 직접 저장할 수도 있다.
- char형 변수에 저장된 값을 int형으로 캐스팅하면 해당 문자의 유니코드를 알 수 있다.
char 타입의 표현형식
- char 타입의 크기는 2byte
- 실제 char타입의 변수 안에는 문자가 아닌 문자의 유니코드(정수)가 저장되고 표현 형식 역시 정수형과 동일
- 정수형과 달리 음수를 나타낼 필요가 없어 표현할 수 있는 값의 범위가 다르다.
- A와 65를 저장했을 때 둘 모두 2진수로는 같은 값이 저장된다.
인코딩과 디코딩
- 문자를 코드로 변환하는 것을 문자 인코딩, 반대로 코드를 문자로 변환하는 것을 문자 디코딩이라 한다.
아스키(ASCII)
- 128개의 문자 집합을 제공하는 7bit 부호.
확장 아스키와 한글
- 아스키는 7bit이므로 남는 1bit까지 문자를 추가로 정의한 것이 확장 아스키
- 확장 아스키도 255개뿐이므로 한글을 표현하기힘듦.
- 조합형과 완성형으로 한글을 표현.
- 현재는 완성형만 사용함.
- 완성형(KSC 5601)
- 확장 완성형(CP 949)
- 한글 윈도우에서의 문자 인코딩
코드 페이지(code page, cp)
- 지역이나 국가에 따른 확장 아스키가 필요했으.ㅁ
- CP xxx와 같은 형식으로 이름을 붙이고 공유함.
유니코드
- 전 세계의 모든 문자를 하나의 통일된 문자 집합으로 표현한 것.
- 인터넷의 발달로 다른 지역과 문서교환이 활발해지면서 필요성 대두
- 2byte로 하려고 했는데 부족해서 21bit를 사용하게 됨.
4.3 정수형 - byte, short, int, long
- 정수형에는 4개의 자료형이 이씅며, 각 자료형이 저장할 수 있는 값의 범위가 서로 다르다.
- byte(1) < short(2) < int(4) < long(8)
- 기본 자료형은 int
정수형의 표현형식과 범위
- 어떤 진법의 리터럴을 변수에 저장해도 실제로는 2진수로 바뀌어 저장된다. 이 2진수가 저장되는 형식은 크게 정수형과 실수형이 있으며, 정수형은 다음과 같은 형식으로 저장된다.
- S(1bit) + n(n-1bit)
- S: 부호비트
- n: 타입의 크기
- 모든 정수형은 부호있는 정수이므로 왼쪽의 첫 번째 비트를 부호비트로 사요하고, 나머지는 값을 표현하는데 사용한다.
- 그래서 n비트로 표현할 수 있는 값의 개수인 2^n개에서, 절반인 ‘0’으로 시작하는 2^(n-1)개의 값을 양수(0을 포함)의 표현에 사용하고 나머지 절반을 ‘1’로 시작하는 음수의 표현에 사용한다.
- 최대값에서 1을 빼는 이유는 범위에 0이 포함되기 때문
정수형의 선택기준
- 변수에 저장하려는 정수값의 범위에 따라 4개의 정수형 중에서 하나를 선택하면 되겠지만, byte나 short보다 int를 사용해야 한다.
- byte와 short가 int보다 크기가 작아 메모리를 조금 더 절약할 수는 있지만, 저장할 수 있는 값의범위가 작은 편이라서 연산시에 범위를 넘어서 잘못된 결과를 얻기가 쉽다.
- JVM의 피연산자 스택(operand stack)이 피연산자를 4byte 단위로 저장하기 때문에 크기가 4byte보다 작은 자료형(byte, short)의 값을 계산할 때는 4byte로 변환하여 연산이 수행된다.
- 따라서 int를 사용하는 것이 오히려 더 효율적이다.
정수형 변수를 선언할 때는 int타입으로 하고, int의 범위(약 +-20억)을 넘어서는 수를 다뤄야 할 때는 long을 사용하면 된다.
정수의 오버플로우
- 연산 과정에서 해당 타입이 표현할 수 있는 값의 범위를 넘어서는 것을 오버플로우라고 한다.
- 오버플로우가 발생했다고 에러가 발생하는 것은 아니다. 다만 예상한 결과를 얻지 못할 뿐이다.
- 정수형 타입이 표현할 수 있는 최대값에 1을 더하면 최소값이 되고, 최소값에서 1을 빼면 최대값이 된다.
부호있는 정수의 오버플로우
- 부호있는 정수는 부호비트가 0에서 1이 될 때 오버플로우가 발생한다.
4.4 실수형 - float, double
실수형의 범위와 정밀도
- 실수를 저장하기 위한 타입으로 float와 double 두가지가 있으며 각 타입의 변수에 저장할 수 있는 값의 범위는 아래와 같다.
- float: 1.4 x 10^-45 ~ 3.4 x 10^38
- double: 4.9 x 10^-324 ~ 1.8 x 10^308
- 실수형도 변수의 값이 표현 범위의 최대값을 벗어나면 오버플로우가 발생함.
- 정수형과 달리 오버플로우가 발생하면 변수의 값은 무한대가 됨.
- 정수형에는 없는 언더플로우가 존재
- 실수형으로 표현할 수 없는 아주 작은 값.
- 양의 최소값보다 작은 값이 되는 경우
- 변수의 값은 0이 된다.
실수형의 저장형식
- 부호(Sign), 지수(Exponent), 가수(Mantissa) 세부분으로 이루어져 있다.
- IEEE754 표준을 따름.
5. 형변환
5.1 형변환(캐스팅, casting)이란?
형변환이란, 변수 또는 상수의 타입을 다른 타입으로 변환하는 것
5.2 형변환 방법
(타입) 피연산자
( )는 ‘캐스트 연산자’ 또는 ‘형변환 연산자’라고 함.
- 피연산자인 변수의 값은 형변환 후에도 아무런 변화가 없다.
- 기본형(primitive type)에서 boolean을 제외한 나머지 타입들은 서로 형변환이 가능하다.
- 기본형과 참조형간의 형변환은 불가능하다.
5.3 정수형간의 형변환
- 큰 타입에서 작은 타입으로의 변환하는 경우 크기의 차이만큼 잘려나간다.
- ‘값 손실(loss of data)가 발생할 수 있다.
- 작은 타입에서 큰 타입으로 변환하는 경우 값 손실이 발생하지 않는다.
- 이후 나머지 빈공간은 0 또는 1로 채워진다.
- 변환하려는 값이 음수인 경우 부호를 유지할 수 있도록 빈 공간을 1로 채운다.
5.4 실수형 간의 형변환
- 실수형에서도 정수형처럼 작은 타입에서 큰 타입으로 변환하는 경우, 빈 공간을 0으로 채운다.
- float타입의 범위를 넘는 값을 float로 형변환 하는 경우는 ‘+-무한대’ 또는 ‘+-0’을 결과로 얻는다.
5.5 정수형과 실수형 간의 형변환
- 정수형과 실수형은 저장형식이 완전히 다르기 때문에 정수형간의 변환처럼 간단히 값을 채우고 자르는 식으로 할 수 없다.
정수형을 실수형으로 변환
- 정수를 2진수로 변환한 다음
- 정규화를 거쳐 실수의 저장형식으로 저장된다.
- 실수형의 정밀도의 제한으로 오차가 발생할 수 있다.
- 10진수 8자리 이상의 값을 실수형으로 변환한다면 double을 사용해야 오차가 발생하지 않는다.
실수형을 정수형으로 변환
- 실수형의 소수점 이하 값은 버려진다.
- 값이 버려지기에 반올림이 발생하지 않는다.
- 소수점을 버리고 남은 정수가 정수형의 저장범위를 넘는 경우 정수의 오버플로우가 발생할 수 있다.
5.6 자동형변환
- 편의상의 이유로 형변환을 생략할 수 있다. 이 경우 컴파일러가 생랴고딘 형변환을 자동적으로 추가해준다.
- 저장할 수 있는 값의 범위보다 더 큰 값을 저장하려는 경우 형변환을 생략하면 에러가 발생한다.
incompatible types: possible lossy conversion from int to byte
- 명시적으로 형변환 해줬을 경우 형변환이 프로그래머의 실수가 아닌 의도적인 것으로 간주하고 컴파일러가 에러를 발생시키지 않는다.
- 서로 다른 두 타입의 연산에서 먼저 타입을 일치시킨 다음 연산을 수행해야 하므로, 연산과정에서 형변환이 자동적으로 이루어진다.
- 두 타입의 연산에서는 표현 범위가 더 넓은 타입으로 형변환하여 타입을 일치시킨 다음 연산을 수행한다.
- 연산 과정에서 자동적으로 발생하는 형변환을 산술 변환이라 한다.
자동 형변환의 규칙
기존의 값을 최대한 보존할 수 있는 타입으로 자동 형변환한다.
- boolean을 제외한 나머지 7개의 기본형은 서로 형변환이 가능하다.
- 기본형과 참조형은 서로 형변환할 수 없다.
- 서로 다른 타입의 변수간의 연산은 형변환을 하는 것이 원칙이지만, 값의 범위가 작은 타입에서 큰 타입으로의 형변환은 생략할 수 있다.