자바 (Java)/요약

Chpt. 2 변수 - 주제 2. 값은 기본형과 참조형으로 나뉜다.

학듄 2023. 10. 17. 16:20
728x90

앞선 주제에서 변수의 타입은 변수에 저장할 값에 따라 달라진다고 했다. 종류(type)를 기준으로 이러한 값들을 크기에 따라 분류한 것을 자료형(data type)이라고 한다. 따라서,

 

모든 값은 종류(type)가 있고 종류(type)를 모르면 해석할 수 없다.

 

1. 변수, 상수, 리터럴

자료형을 알아보기에 앞서 변수, 상수, 리터럴의 정의에 대해 알아보자.

 

변수: 하나의 값을 저장하는 공간

상수: 한 번만 저장할 수 있는 변수

리터럴: 그 자체로 값을 의미하는 것

 

사실 리터럴은 기존 수학에서의 상수를 뜻하지만 자바에서는 위와 같이 상수를 정의했기 때문에 차이점을 주기 위해 리터럴이라는 용어를 따로 붙어준 것이다.

상수는 기존 변수를 선언, 초기화하는 방법과 같지만 앞에 final이라는 키워드를 붙이며 한 번 초기화를 하고 다른 값을 대입하려고 하면 에러가 발생한다. 또한 선언과 동시에 초기화를 하지 않아도 된다.

 

2. 기본형과 참조형

자료형은 기본형과 참조형으로 나눠지는데 다음과 같은 특징을 갖고 있다.

 

  저장되는 값
기본형 실제 값 = 리터럴 false, 123, 1.45, 'B', "ABCD"
참조형 메모리 주소 = 객체의 주소 0x00

 

객체의 주소에 대해서는 객체 지향에서 다시 다루도록 한다.

 

1) 기본형의 종류

기본형은 아래의 표와 같이 8개의 타입이 있으며 외우도록 한다. 기본형 이외의 값은 모두 참조형으로 생각한다.

 

  1 byte (= 8 bit) 2 byte 4 byte 8byte
논리형 boolean      
문자형   char    
정수형 byte short int long
실수형     float double

 

 

2) 기본형의 범위

기본형은 0과 1 두 값으로 표현할 수 있는 bit 형식으로 저장된다. 그렇기 때문에 저장 공간의 크기(bit)와 저장 형식(부호 유무)에 따라 각 타입의 저장 가능한 값의 범위가 달라진다. short와 char 두 예시를 통해 알아보자.

 

[예 1] char의 범위

char의 크기는 2 byte, 즉 16 bit로 표현할 수 있는 값이다. 따라서 char로 표현할 수 있는 정수 값의 범위는 0 ~ 2 n-1이다.

 

[예 2] short의 범위

S의 값이 0일 때는 양수, 1일 때는 음수이다.

short의 크기는 2 byte, 즉 16 bit로 표현할 수 있는 값이다. 하지만 정수형이기 때문에 문자형과 다르게 부호 또한 표현해주어야 한다.  이를 위해 맨 앞 비트를 부호 비트(sign bit)로 할당했다. 따라서 0과 양수를 포함한 215개,  음수 215개, 총 2 X 215 = 216개의 정수를 표현할 수 있다. 범위로 나타내면 -2n-1 ~ 0 ~ 2n-1-1이다.  

 

위 두 예시를 정리하면 다음과 같다.

 

부호 있는 정수의 범위 0 ~ 2n-1

부호 없는 정수의 범위 -2n ~ 2n-1-1

 

이와 함께 정수형 int는 -2 31 ~ 2 31 -1, 약 ±20억의 값을 저장할 수 있다는 사실 또한 알아두자. 그리고 이와 같은 저장 형식 때문에 float(정밀도 약 7)과 double(정밀도 약 15)은 정밀도 면에서 차이가 난다.

 

3. 리터럴의 구분

리터럴의 구분은 접두사 또는 접미사로 한다.

 

종류 리터럴 접미사
논리형 false, true 없음
정수형 100, 0b100, 0100, 0x100, 100L, 100_000 L
실수형 3.14, 10., .10, 10f, 1e-3 f, d
문자형 'A', '2', '\n' 없음
문자열 "", "A", "ABC", "false" 없음

 

1) 논리형

false, true 두 가지 값만 허용한다.

 

2) 정수형

접두사 0b, 0, 0x은 각각 2진수, 8진수, 16진수를 표현하기 위해 사용된다. 접미사 L은 숫자 1과 혼동하지 않기 위해 대문자로 쓰는 것을 권장한다. 또한 크기가 큰 정수인 경우 구분자(_)를 통해 자리수를 구별할 수 있다.

 

3) 실수형

실수형에는 두 가지 타입 float과 double만 있기 때문에 접미사 f로 둘을 구별한다. f는 생략할 수 없지만 d는 생략 가능하다.

 

[참고]

10. = 10.0

.10 = 0.10

10f = 10.0f

1e-3 = 1.0 x 10 -3

 

4) 문자형과 문자열

문자형은 작은 따옴표 안에 한 개의 문자가 들어가지만 문자열은 큰 따옴표 안에 0개에서 n개의 문자가 들어갈 수 있다. 참고로 \n은 하나의 문자로 취급하는 이스케이프 문자라고 한다.

 

결국 리터럴을 구분할 때는 접미사 L과 f만 신경쓰면 된다.

 

4. 값의 입력과 출력

System.out.println()은 출력 형식을 지정할 수 없고, 10진수로만 출력이 가능하다라는 단점을 갖고 있다. 이와 같은 단점을 보완하기 위해 System.out.printf() (이하 printf()) 를 사용하며 printf()는  지시자를 사용해 여러 변수의 값을 다양한 형식으로 변환해 출력하게 된다.

 

1) 값의 출력

[예 1] %d, %n

 

int age = 26;
int bornYear = 1998;
System.out.printf("Your were born in %d, and age is %d.%n", bornYear, age);

 

출력 결과는 Your were born in 1998, and age is 26.이며 지시자의 개수에 제한은 없다. printf()는 줄바꿈이 되지 않기 때문에 OS에 독립적인 %n을 쓰도록 한다. 

 

[참고]

지시자 %o, %x를 통해 각각 8진수, 16진수의 정수 형태로 출력할 수 있지만 2진수는 Integer.toBinaryString()을 이용해 출력하도록 한다.

 

[예 2] %f

실수형의 값을 출력할 때 다음과 같은 방법으로 전체 자리수와 소수점 아래 자리수의 출력 형식을 지정할 수 있다.

 

%[0-][전체 자리수].[소수점 자리수]f

 

double pi = 3.1415;
System.out.printf("Pi is <%16.10f>.%n", pi);
System.out.printf("Pi is <%-16.10f>.", pi);
System.out.printf("Pi is <%016.10f>.%n", pi);
[결과]
Pi is <    3.1415000000>.
Pi is <3.1415000000    >.
Pi is <00003.1415000000>.

 

위 결과는 아래 그림을 참고하면 이해할 수 있다. 참고로 오른쪽 정렬이 기본이며 전체 자리수 앞에 -를 붙이면 왼쪽으로 정렬된다. 또한 - 대신 0을 붙이면 왼쪽 빈자리는 0으로 채워진다.

왼쪽 빈자리는 공백으로, 오른쪽 빈자리는 0으로 채워진다.

 

[예 3] %s

[예 2]와 비슷한 방법으로 문자형의 출력할 글자 수를 조절할 수 있다.

 

%[-][전체 자리수]s

 

String sentence = "You are my celebrity";
System.out.printf("<%30s>%n", sentence);
System.out.printf("<%-30s>%n", sentence);
System.out.printf("%.10s", sentence);
[결과]
<          You are my celebrity>
<You are my celebrity          >
You are my

 

맨 마지막 줄의 결과를 보자. .을 붙이면 맨 마지막 줄의 결과처럼 원하는 만큼의 글자 수를 정해 출력할 수 있다. 

 

2) 값의 입력

값의 입력은 import문을 먼저 추가하고, Scanner 클래스의 객체를 생성 후, nextLine() 메서드를 사용한다. 입력받은 내용은 문자열 형태이고 만약 정수형으로 바꾸고 싶다면 Integer.parseInt([입력받은 값]) 클래스 메서드를 사용하도록 한다. 만약 입력 받은 내용이 정수 하나라면 nextInt()를 바로 사용해 변수에 저장해도 된다. 일단은 이렇게만 알아두고 자세한 내용은 클래스에 가서 다루도록 하겠다.

 

import java.util.*;

Scanner scanner = new Scanner(System.in);

// 방법 1
String input = scanner.nextLine();
int num1 = Integer.parseInt(input);

// 방법 2 - 공백과 함께 100 200을 입력하면 num2와 num3에 각각 100, 200이 저장된다.
int num2 = scanner.nextInt();
int num3 = scanner.nextInt();

 

 

5. 정수형의 오버플로우

 

최대값 + 1 = 최소값

최소값 - 1 = 최대값

 

위의 두 문장만 기억하면 된다. 쉬운 예로 TV의 마지막 채널에서 채널을 하나 올리면 처음 채널로 돌아가고 처음 채널에서 하나 내리면 마지막 채널로 간다.

반응형