| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- 자료구조
- 자바
- 1일1코테
- 프로그래밍 언어
- 인접 행렬
- til
- 항해99
- 갭체크
- 오블완
- C
- 티스토리챌린지
- 코딩테스트준비
- 파이썬
- 프로그래머스
- 코테공부
- 플로이드-워셜
- 개발자취업
- 개발자루틴
- 코드트리
- 웹
- 코딩테스트사이트추천
- 99클럽
- 연결 리스트
- 데이터베이스
- 코딩테스트
- Java
- 자바스크립트
- #코드트리 #코딩테스트 #코테공부 #백트래킹 #알고리즘 기초
- 운영체제
- 알고리즘
- Today
- Total
와드의 블로그
Chapter 2. 변수 본문
1. 변수
1.1 변수란?
변수란 값을 저장할 수 있는 메모리 상의 공간을 의미한다. 하나의 변수에 단 하나의 값만 저장할 수 있으므로, 새로운 값을 저장하면 기존의 값은 사라진다.
1.2 변수의 선언과 초기화
※ 변수의 선언
변수를 사용하려면 먼저 변수를 선언해야 한다. 변수의 선언 방법은 다음과 같다.
int age; // int: 변수 타입, age: 변수 이름
변수 타입은 변수에 저장될 값이 어떤 타입인지를 지정하는 것이다. 저장하고자 하는 값의 종류에 맞게 변수의 타입을 선택하여 적어주면 된다. 자바는 정수형, 실수형, 문자형 등 다양한 타입을 제공한다.
변수 이름은 말 그대로 변수에 붙인 이름이다. 변수는 값을 저장할 수 있는 메모리 공간이므로 변수 이름은 메모리 공간에 이름을 붙여주는 것이다. 그래서 그 이름을 이용해 저장 공간에 접근할 수 있다.
※ 변수의 초기화
변수를 선언한 이후부터는 변수를 사용할 수 있으나, 그전에 반드시 변수를 초기화해야 한다. 메모리는 여러 프로그램이 공유하는 자원이므로 전에 다른 프로그램에 의해 저장된 쓰레기 값이 남아있을 수 있기 때문이다.
변수에 값을 저장할 때는 대입 연산자(=)를 이용한다. 대입 연산자를 사용하면 연산자 오른쪽의 값을 왼쪽에 저장한다.
int age = 25; // 변수 age를 선언하고 25로 초기화
즉, 변수의 초기화란 변수를 사용하기 전에 처음으로 값을 저장하는 것이다.
※ 두 변수의 값 교환하기
변수 x, y가 있을 때, 두 변수에 담긴 값을 서로 바꾸려면 어떻게 해야 할까? 단순하게 변수 y의 값을 x에 저장하고, x의 값을 y에 저장하면 될 것 같지만 그렇게 해서는 원하는 결과를 얻을 수 없다. 왜냐하면 x에 변수 y의 값을 저장하는 순간 원래 x의 값이 사라지기 때문이다.
public class Variable {
public static void main(String[] args) {
int x = 10, y = 20;
System.out.println("x: " + x + " y: " + y); // x: 10 y: 20
x = y;
y = x;
System.out.println("x: " + x + " y: " + y); // x: 20 y: 20
}
}
그렇다면 어떻게 해야 할까? 임시 변수를 하나 더 선언해서 값을 x의 값을 임시로 저장한 후 x에 변수 y의 값을 저장하고 y에 임시로 저장해 둔 x의 값을 저장하면 된다.
public class Variable {
public static void main(String[] args) {
int x = 10, y = 20;
System.out.println("x: " + x + " y: " + y); // x: 10 y: 20
int tmp = x;
x = y;
y = tmp;
System.out.println("x: " + x + " y: " + y); // x: 20 y: 10
}
}
1.3 변수의 명명 규칙
변수의 이름처럼 프로그래밍에서 사용하는 모든 이름을 식별자라고 하며, 식별자는 같은 영역 내에서 서로 구분될 수 있어야 한다. 자바의 식별자 명명 규칙은 다음과 같다.
- 대소문자는 구분되며 길이에 제한이 없다.
- 예약어를 사용해서는 안 된다.
- 숫자로 시작해서는 안 된다.
- 특수문자는 _와 $만을 허용한다.
그 외에 필수적인 것은 아니지만 자바 프로그래머들에게 권장하는 규칙은 다음과 같다.
- 클래스 이름의 첫 글자는 항상 대문자로 한다.
- 여러 단어로 이루어진 이름은 두 번째 단어부터 단어의 첫 글자를 대문자로 한다.
- 상수의 이름은 모두 대문자로 하고 여러 단어로 이루어진 경우 _로 구분한다.
변수의 이름은 짧을수록 좋지만, 약간 길더라도 용도를 알기 쉽게 의미 있는 이름으로 하는 것이 바람직하다.
2. 변수의 타입
2.1 자료형
우리가 사용하는 값의 종류에 따라 값이 저장될 공간의 크기와 저장 형식을 정의한 것이 자료형이다. 자료형에는 문자형, 정수형, 실수형 등이 있으며, 변수를 선언할 때는 저장하려는 값의 특성을 고려하여 가장 알맞은 자료형을 변수 타입으로 선택하면 된다.
※ 기본형과 참조형
자료형은 크게 기본형과 참조형으로 나눌 수 있다. 기본형 변수는 실제 값을 저장하는 반면, 참조형 변수는 어떤 값이 저장되어 있는 주소를 값으로 갖는다.
변수의 타입이 기본형이 아닌 것들은 모두 참조형이다. 객체는 변수의 타입으로 클래스 이름을 사용하므로 모두 참조형 변수가 된다.
2.2 기본형
기본형에는 모두 8개의 타입이 있으며, 크게 논리형, 문자형, 정수형, 실수형으로 구분된다.

문자형인 char는 문자를 내부적으로 정수로 저장하기 때문에 정수형과 별반 다르지 않으며, 정수형 또는 실수형과 연산도 가능하다. 반면에 boolean은 다른 기본형과 연산이 불가능하다.
정수형은 가장 많이 사용되므로 타입을 4가지나 제공한다. 각 타입마다 저장할 수 있는 값의 범위가 다르므로 저장할 값의 범위에 맞는 타입을 선택하면 된다.
실수형은 정수형과 저장 형식이 달라서 같은 크기라도 훨씬 큰 값을 표현할 수 있으나 오차가 발생할 수 있다는 단점이 있다.
2.3 상수와 리터럴
※ 상수와 리터럴
상수는 변수와 마찬가지로 값을 저장할 수 있는 공간이지만, 변수와 달리 한 번 값을 저장하면 다른 값으로 변경할 수 없다. 상수를 선언하는 방법은 변수와 동일하며, 단지 변수의 앞에 final 키워드를 붙여주기만 하면 된다. 그리고 상수는 반드시 선언과 동시에 초기화해야 한다.
상수의 이름은 모두 대문자로 하는 것이 암묵적인 관례이며, 여러 단어로 이루어져 있는 경우 _로 구분한다.
final int MAX_SPEED = 10;
12, 'A', 3.14와 같은 값들을 리터럴이라고 한다. 리터럴은 주로 변수에 저장되어 사용된다.
※ 리터럴의 타입과 접미사
변수에 타입이 있는 것처럼 리터럴에도 타입이 있다.
정수형과 실수형에는 여러 타입이 존재하므로, 리터럴에 접미사를 붙여서 타입을 구분한다. 정수형의 경우 long 타입의 리터럴에 접미사 l이나 L을 붙이고, 접미사가 없으면 int 타입의 리터럴이다. byte나 short 타입의 리터럴은 따로 존재하지 않는다.
정수형 리터럴에는 10진수 외에도 2, 8, 16진수로 표현된 리터럴을 사용할 수 있다. 16진수 리터럴에는 접두사 0X나 0x를 붙이고, 8진수는 0, 2진수는 0b를 붙인다.
실수형에서는 float 타입의 리터럴에 접미사 f 또는 F를 붙이고, double 타입의 리터럴에는 접미사 d 또는 D를 붙인다. 실수형에서는 double이 기본 자료형이라서 접미사의 생략이 가능하다.
리터럴의 타입은 저장될 변수의 타입과 일치하는 것이 보통이지만, 타입이 달라도 저장 범위가 넓은 타입에 좁은 타입의 값을 저장하는 것은 허용된다.
※ 문자 리터럴과 문자열 리터럴
'A'와 같이 작은따옴표로 문자 하나를 감싼 것을 문자 리터럴이라고 한다. 두 문자 이상은 큰 따옴표로 감싸야하며 문자열 리터럴이라고 한다. char 타입의 변수는 문자 리터럴만 저장할 수 있고 문자열 리터럴을 저장하기 위해서는 String 타입을 사용한다.
char c = 'A';
String s = "Java";
문자열은 덧셈 연산자를 이용하여 결합할 수 있다. 덧셈 연산자는 피연산자가 모두 숫자일 때는 두 수를 더하지만, 피연산자 중 어느 한쪽이 String이면 나머지 한쪽을 String으로 변환한 다음 두 String을 결합한다.
2.4 형식화된 출력
지금까지 화면에 출력할 때 println()을 써왔는데, println()은 사용하기에 편하지만 변수의 값을 그대로 출력한다. printf()는 형식을 지정해서 값을 여러 형식으로 출력할 수 있다.
printf()는 지시자를 통해 변수의 값을 여러 가지 형식으로 변환하여 출력하는 기능을 가지고 있다. 지시자는 값을 어떻게 출력할 것인지를 지정해주는 역할을 한다. prinf()에서 자주 사용되는 지시자는 다음과 같다.

정수를 출력할 때는 지시자 %d를 사용하는데, 출력될 값이 차지할 공간을 숫자로 지정할 수 있다.
public class Variable {
public static void main(String[] args) {
int a = 10;
System.out.printf("[%5d]%n", a); // [ 10]
System.out.printf("[%-5d]%n", a); // [10 ]
System.out.printf("[%05d]%n", a); // [00010]
}
}
지시자 %x와 %o에 #을 사용하면 접두사 0x와 0이 붙어서 출력된다. %X는 16진수와 접두사를 대문자로 출력한다.
public class Variable {
public static void main(String[] args) {
int hex = 0xffffffff;
System.out.printf("%x%n", hex); // ffffffff
System.out.printf("%#x%n", hex); // 0xffffffff
System.out.printf("%#X%n", hex); // 0XFFFFFFFF
}
}
10진수를 2진수로 출력해주는 지시자는 없기 때문에, 정수를 2진 문자열로 변환해주는 Integer.toBinaryString()를 사용해야 한다. 이 메서드는 정수를 2진수로 변환해서 문자열로 반환한다.
public class Variable {
public static void main(String[] args) {
int bi = 0b10;
System.out.printf("%s%n", Integer.toBinaryString(bi)); // 10
}
}
실수형 값의 출력에 사용되는 지시자는 %f와 %e가 있는데 %f가 주로 쓰이고 %e는 지수 형태로 출력할 때 사용된다.
%f는 기본적으로 소수점 아래 6자리까지만 출력하기 때문에 소수점 아래 7자리에서 반올림한다. %f에서는 전체 자릿수와 소수점 아래의 자릿수를 지정할 수도 있다.
public class Variable {
public static void main(String[] args) {
double d = 1.23456789;
System.out.printf("%f%n", d); // 1.234568
System.out.printf("[%14.10f]%n", d); // [ 1.2345678900]
}
}
지시자 %s에도 숫자를 추가하면 원하는 만큼의 출력 공간을 확보하거나 문자열의 일부만 출력할 수 있다.
public class Variable {
public static void main(String[] args) {
String s = "abcdefghijklmn";
System.out.printf("[%s]%n", s); // [abcdefghijklmn]
System.out.printf("[%20s]%n", s); // [ abcdefghijklmn]
System.out.printf("[%-20s]%n", s); // [abcdefghijklmn ]
System.out.printf("[%.8s]%n", s); // [abcdefgh]
}
}
2.5 화면에서 입력받기
지금까지는 화면에 출력만 해왔는데, 이제 화면으로부터 입력받는 방법에 대해 배워보자. 자바에서는 Scanner 클래스를 이용해서 화면으로부터 입력받을 수 있다.
import java.util.*; // Scanner 클래스를 사용하기 위해 추가
public class Variable {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // Scanner 클래스의 객체 생성
System.out.print("두자리 정수를 하나 입력하세요: ");
String input = scanner.nextLine(); // 입력 받은 내용을 input에 저장
int n = Integer.parseInt(input); // 입력 받은 내용을 int 타입으로 변환
System.out.println(input);
System.out.printf("%d%n", n);
}
}
Scanner 클래스를 사용하기 위해서 import java.util.*라는 문장을 추가하고 Scanner 객체를 생성하고 nextLine() 메서드를 호출해서 화면에서 입력받는다.
3. 진법
3.1 10진법과 2진법
우리는 일상생활에서 주로 10진법을 사용한다. 하지만 컴퓨터는 2진 체계로 설계되었기 때문에 2진법을 알지 못하면 컴퓨터의 동작 원리나 데이터 처리 방식을 온전히 이해할 수 없다.
2진법은 0과 1로만 데이터를 표현하기 때문에 10진법에 비해 많은 자릿수를 필요로 한다. 자릿수가 많아지긴 해도 2진수는 10진수를 온전히 표현할 수 있다. 게다가 덧셈과 뺄셈 같은 연산도 10진수와 동일하다.
3.2 비트와 바이트
한 자릿수의 2진수를 비트라고 하며, 1 비트는 컴퓨터가 값을 저장할 수 있는 최소 단위이다. 그러나 1 비트는 너무 작은 단위이기 때문에 1 비트 8개를 묶어서 바이트라는 단위로 정의해서 데이터의 기본 단위로 사용한다. 이외에도 워드라는 단위가 있는데 워드는 CPU가 한 번에 처리할 수 있는 데이터의 크기를 의미하고 CPU의 성능에 따라 1 워드는 32비트 또는 64비트이다.
n 비트로는 2^n개의 값을 표현할 수 있다. 그리고 n 비트로 10진수를 표현한다면, 표현 가능한 10진수의 범위는 0 ~ 2^n-1이다.
3.3 8진법과 16진법
2진법은 오직 0과 1, 두 개의 기호만으로 값을 표현하기 때문에, 2진법으로 값을 표현하면 자릿수가 상당히 길어진다는 단점이 있다. 이러한 단점을 보완하기 위해 2진법 대신 8진법이나 16진법을 사용한다.
8진법은 2진수 3자리를, 16진수는 2진수 4자리를 각각 한자리로 표현할 수 있기 때문에 자릿수가 짧아져서 알아보기 쉽고 서로 간의 변환 방법도 매우 간단하다.
※ 2진수를 8진수, 16진수로 변환
2진수를 8진수로 변환하려면, 2진수를 뒤에서부터 3자리씩 끊어서 그에 해당하는 8진수로 바꾸면 된다. 마찬가지로 2진수를 16진수로 변환하려면, 2진수를 뒤에서부터 4자리씩 끊어서 그에 해당하는 16진수로 바꾸면 된다.
3.4 정수의 진법 변환
※ 10진수를 n진수로 변환
10진수를 다른 진수로 변환하려면, 해당 진수로 나누고 나머지 값을 옆으로 적는 것을 더 이상 나눌 수 없을 때까지 반복한 다음 마지막 몫과 나머지를 아래부터 위로 순서대로 적으면 된다.

※ n진수를 10진수로 변환
어떤 진법의 수라도 10진수로 변환하는 방법은 똑같다. 각 자리의 수에 해당 단위의 값을 곱해서 모두 더하면 된다.

3.5 실수의 진법 변환
※ 10진 소수를 2진 소수로 변환하는 방법
앞서 10진 정수를 2진 정수로 변환할 때, 10진수를 2로 계속 나누면서 나머지를 구했다. 10진 소수를 2진 소수로 변환하는 방법은 이와 반대로 10진 소수에 소수부가 0이 될 때까지 2를 계속 곱하는 것이다.

※ 2진 소수를 10진 소수로 변환하는 방법
2진 소수를 10진 소수로 변환하는 방법은 2진수를 10진수로 변환하는 방법과 같이 각 자리의 수에 해당 단위의 값을 곱해서 모두 더하면 된다.
3.6 음수의 2진 표현
n 비트의 2진수로 표현할 수 있는 값의 개수는 모두 2^n개 이므로 이 값을 부호 없는 정수의 표현에 사용하면 0부터 2^n-1까지의 정수를 표현할 수 있다.
그렇다면 n 비트의 2진수로 부호 있는 정수를 표현하려면 어떻게 해야 할까? 왼쪽의 첫 번째 비트를 부호를 나타내는 비트로 만들어서 0이면 양수, 1이면 음수를 나타내도록 한다. 그러면 -2^(n-1)부터 2^(n-1)-1의 값을 표현할 수 있다. 이후 2의 보수법에 의해 음수를 표현한다.
※ 2의 보수법
어떤 수의 n의 보수는 더했을 때 n이 되는 수를 말한다. 2의 보수는 더해서 2가 되는 두 수의 관계를 말하며 2진수의 2의 보수는 더했을 때 자리올림이 발생하고 0이 되는 두 수를 말한다.
※ 음수를 2진수로 표현하기
10진 음의 정수를 2진수로 변환하려면, 먼저 10진 음의 정수의 절댓값을 2진수로 변환한다. 그다음에 이 2진수의 2의 보수를 구하면 된다.
※ 2의 보수 구하기
2의 보수를 구하는 방법은 간단하다. 1의 보수를 구한 다음 1을 더하면 2의 보수를 구할 수 있다. 1의 보수는 0을 1로 1을 0으로만 바꾸면 되므로 구하기 쉽다.
4. 기본형
4.1 논리형
논리형에는 boolean 한 가지밖에 없다. boolean형 변수에는 true와 false 중 하나를 저장할 수 있으며 기본값은 false이다. boolean형은 true와 false, 두 가지 값만을 표현하면 되므로 1 bit만으로도 충분하지만, 자바에서는 데이터를 다루는 최소 단위가 바이트이므로 boolean의 크기는 1 byte이다.
4.2 문자형
문자형 역시 char, 한 가지 자료형밖에 없다. 문자를 저장하기 위한 변수를 선언할 때 사용되며, char 타입의 변수는 단 하나의 문자만을 저장할 수 있다. char 형 변수에 문자를 저장하면 문자가 저장되는 것 같지만, 사실은 문자가 아닌 문자의 유니코드인 정수가 저장된다. 컴퓨터는 숫자만을 처리하기 때문에 모든 데이터를 숫자로 변환하여 저장한다.
※ 특수 문자 다루기
영문자 외에 tab이나 backspace 등의 특수 문자를 저장하려면, 아래와 같은 특수 표현을 사용한다.
- tab: \t
- backspace: \b
- new line: \n
- 역슬래쉬: \\
- 작은따옴표: \'
- 큰 따옴표: \"
4.3 정수형
정수형에는 모두 4개의 자료형(byte, short, int, long)이 있으며, 각 자료형이 저장할 수 있는 값의 범위가 서로 다르다. 기본 자료형은 int다.
※ 정수형의 표현 형식과 범위
어떤 진법의 리터럴을 변수에 저장해도 실제로는 2진수로 바뀌어 저장된다. 모든 정수형은 부호 있는 정수이므로 왼쪽 첫 번째 비트를 부호 비트로 사용하고 나머지를 값을 표현하는 데 사용한다. 그래서 n비트로 표현할 수 있는 값의 범위는 -2^(n-1) ~ 2(n-1)-1이다.
※ 정수형의 선택 기준
변수에 저장하려는 정수 값의 범위에 따라 4개의 정수형 중에서 하나를 선택하면 되겠지만, byte나 short보다 int를 사용하는 것이 좋다. byte와 short는 저장할 수 있는 값의 범위가 작아서 연산 시에 범위를 넘어서 잘못된 결과를 얻기 쉽다. 따라서 정수형 변수를 선언할 때는 int 타입을 사용하고, int의 범위를 넘어서는 수를 다뤄야 할 때는 long을 사용한다.
※ 정수형의 오버플로우
연산 과정에서 해당 타입이 표현할 수 있는 값의 범위를 넘어서는 것을 오버플로우라고 한다. 오버플로우가 발생했다고 해서 에러가 발생하는 것은 아니지만 예상했던 결과를 얻지 못한다.
정수형 타입이 표현할 수 있는 최댓값에서 1을 더하면 최솟값이 되고 최솟값에서 1을 빼면 최댓값이 된다.
4.4 실수형
※ 실수형의 범위와 정밀도
실수형은 실수를 저장하기 위한 타입으로 float와 double, 두 가지가 있으며 각 타입의 변수에 저장할 수 있는 값의 범위는 다음과 같다.

위 범위는 양의 범위만 적은 것으로, 이 범위에 -를 붙이면 음의 범위가 된다.
실수형은 부호, 지수, 가수, 세 부분으로 이루어져 있다. 따라서 이렇게 큰 범위의 값을 저장하는 것이 가능하다.
하지만 정수형과 달리 실수형은 오차가 발생할 수 있다는 단점이 있다. 그래서 실수형에는 표현할 수 있는 값의 범위뿐만 아니라 정밀도도 중요한 요소이다. float 타입은 정밀도가 7자리이고 double 타입은 정밀도가 15자리이다.
※ 실수형의 오버플로우
실수형에서도 정수형과 마찬가지로 변수의 값이 표현 범위의 최댓값을 벗어나면 오버플로우가 발생한다. 정수형과 달리 실수형에서는 오버플로우가 발생하면 변수의 값이 무한대가 된다.
그리고 정수형에는 없는 언더플로우가 잇는데, 언더플로우는 실수형으로 표현할 수 없는 아주 작은 값이 되는 경우를 말한다. 이때 변수의 값은 0이 된다.
※ 실수형의 저장 형식
실수형은 정수형과 표현 형식이 다르다. 실수형은 값을 부동소수점의 형태로 저장한다. 부동소수점은 실수를 ±M*2^E와 같은 형태로 표현하는 것을 말하며, 부동소수점은 부호, 지수, 가수, 세 부분으로 이루어져 있다.

※ 부동 소수점의 오차
실수 중에는 파이와 같은 무한 소수가 존재하므로, 정수와 달리 실수를 저장할 때는 오차가 발생할 수 있다. 게다가 10진수가 아닌 2진수로 저장되기 때문에 10진수로는 유한 소수이더라도, 2진수로 변환하면 무한 소수가 되는 경우도 있다. 또한 비록 2진수가 유한 소수라도, 가수를 저장할 수 있는 자릿수가 한정되어 있으므로 저장되지 못하고 버려지는 값들이 있으면 오차가 발생한다.
5. 형 변환
5.1 형 변환이란?
모든 변수와 리터럴에는 타입이 있다. 프로그램을 작성하다 보면 같은 타입뿐만 아니라 서로 다른 타입 간의 연산을 수행해야 하는 경우가 있다. 이럴 때는 연산을 수행하기 전에 타입을 일치시켜야 하는데, 변수나 리터럴의 타입을 다른 타입으로 변환하는 것을 형 변환이라고 한다.
5.2 형 변환 방법
형 변환 방법은 아주 간단하다. 형 변환하고자 하는 변수나 리터럴의 앞에 변환하고자 하는 타입을 괄호와 함께 붙여주기만 하면 된다. 여기에 사용되는 괄호()는 형 변환 연산자라고 한다.
public class Variable {
public static void main(String[] args) {
double d = 85.4;
int a = (int)d;
System.out.println("a=" + a); // a=85
System.out.println("d=" + d); // d=85.4
}
}
형 변환 연산자는 그저 피연산자의 값을 읽어서 지정된 타입으로 형 변환하고 그 결과를 반환할 뿐이다. 그래서 피연산자인 변수의 값은 형 변환 후에도 아무런 변화가 없다.
기본형에서 boolean을 제외한 나머지 타입들은 서로 형 변환이 가능하다. 그리고 기본형과 참조형 간의 형 변환은 불가능하다.
5.3 정수형 간의 형 변환
큰 타입에서 작은 타입으로의 변환에서는 크기의 차이만큼 잘려나간다. 그래서 경우에 따라 값 손실이 발생할 수 있다. 반대로 작은 타입에서 큰 타입으로의 변환에서는 저장 공간의 부족으로 잘려나가는 일이 없으므로 값 손실이 발생하지 않는다. 그리고 나머지 빈 공간은 0 또는 1로 채워진다.
5.4 실수형 간의 형 변환
실수형에서도 정수형처럼 작은 타입에서 큰 타입으로 변환하는 경우, 빈 공간을 0으로 채운다. 반대로 큰 타입에서 작은 타입으로 변환하는 경우, 넘치는 부분은 버려진다.
5.5 정수형과 실수형 간의 형 변환
※ 정수형을 실수형으로 변환
정수는 소수점 이하의 값이 없으므로 비교적 변환이 간단하다. 그저 정수를 2진수로 변환한 다음 정규화를 거쳐 실수의 저장 형식으로 저장된다. 실수형은 정수형보다 훨씬 큰 저장 범위를 갖기 때문에, 정수형을 실수형으로 변환하는 것은 별 무리가 없다. 보통 float 형은 정밀도 차이에 의한 오차가 발생할 수 있지만 double 형은 오차가 발생하지 않는다.
※ 실수형을 정수형으로 변환
실수형을 정수형으로 변환하면, 실수형의 소수점 이하 값은 버려진다. 정수형 표현 형식으로 소수점 이하의 값을 표현할 수 없기 때문이다. 만일 실수의 소수점을 버리고 남은 정수가 정수형의 저장 범위를 넘는 경우에는 정수의 오버플로우가 발생한 결과를 얻는다.
5.6 자동 형 변환
서로 다른 타입 간의 대입이나 연산을 할 때, 형 변환으로 타입을 일치시키는 것이 원칙이다. 하지만 경우에 따라 편의상의 이유로 형 변환을 생략할 수 있다. 그렇다고 해서 형 변환이 이루어지지 않는 것은 아니고, 컴파일러가 생략된 형 변환을 자동으로 추가한다.
변수에 값을 저장할 때 넓은 범위의 타입에 좁은 범위의 값을 저장할 때는 형 변환을 생략해도 자동으로 형 변환이 일어난다. 그러나 변수가 저장할 수 있는 값의 범위보다 더 큰 값을 저장하려는 경우에 형 변환을 생략하면 에러가 발생한다.
또 연산 과정에서 자주 형 변환이 생략되는데, 서로 다른 두 타입의 연산에서는 먼저 타입을 일치시킨 다음에 연산을 수행해야 하므로, 연산 과정에서 형 변환이 자동적으로 이루어진다.
※ 자동 현 변환의 규칙
형 변환을 생략하면 컴파일러가 자동으로 형 변환을 한다. 그렇다면 컴파일러는 어떤 기준으로 타입을 일치시킬까? 컴파일러는 표현 범위가 좁은 타입에서 넓은 타입으로 형 변환하는 경우에 값 손실이 없으므로 두 타입 중에서 표현 범위가 넓은 쪽으로 형 변환한다.
'프로그래밍 언어 > Java' 카테고리의 다른 글
| Chapter 6. 객체지향 프로그래밍 1 (0) | 2022.12.05 |
|---|---|
| Chapter 5. 배열 (0) | 2022.12.03 |
| Chapter 4. 조건문과 반복문 (0) | 2022.11.28 |
| Chapter 3. 연산자 (0) | 2022.11.24 |
| Chapter 1. 자바의 시작 (0) | 2022.11.23 |