Java

[자바의 정석] #CH.2 변수 Variable - 2.2 변수의 타입

소댓 2023. 1. 16. 16:56

2. 변수의 타입

- 변수의 타입은 저장할 값의 타입에 의해 결정된다.

- 저장할 값의 타입과 일치하는 타입으로 변수를 선언

int age = 25; // int는 정수 타입

char ch = '가'; // char는 문자 타입

double pi = 3.14; // double은 실수 타입

 

* 기본형과 참조형

- 기본형(primitive type) > 오직 8개

: 논리형(boolean), 문자형(char), 정수형(byte, short, int, long), 실수형(float, double) 계산을 위한 실제 값을 저장. 모두 8개

  실제 값을 저장함

- 참조형(reference type)

: 객체의 주소를 저장한다. 8개의 기본형을 제외한 나머지 타입 > String(32bit JVM), System(64bit JVM) 등

  메모리 주소를 저장(4byte 또는 8byte)

  클래스이름 변수이름; // 변수의 타입이 기본형이 아닌 것들은 모두 참조변수이다.

  Date today; // 참조형 변수 today를 선언

  today = new Date (); // Date객체를 생성해서, 그 주소를 today에 저장

 

 

2.1 기본형(primitive type)

 

* 기본형의 종류와 크기

- 논리형 (boolean)

: true와 false 중 하나를 값으로 갖으며, 조건식과 논리적 계산에 사용된다.

- 문자형 (char)

: 문자를 저장하는데 사용되며, 변수에 하나의 문자만 저장할 수 있다.

- 정수형 (byte, short, int, long)

: 정수를 저장하는데 사용되며, 주로 int가 사용된다.

  byte는 이진 데이터를 다룰 때 사용되며, short은 C언어와의 호환을 위해서 추가되었다.(short는 잘 안쓰임)

- 실수형 (float, double)

: 실수를 저장하는데 사용되며, 주로 double이 사용된다.

>> 총 8개의 기본형 종류가 존재

종류/크기 1byte(=8bit) 2byte(=16bit) 4byte(=32bit) 8byte(=64bit)
논리형 boolean      
문자형   char    
정수형 byte
(-128~127)
short
(O:-32768~32767)
(X:0~65535)
int
(-20억~20억)
long
(-800경~800경)
실수형     float
(정밀도 - 7자리)
double
(정밀도 - 15자리)

(**정수형에서는 int, 실수형에서는 double이 디폴트 타입) 

> n비트로 표현할 수 있는 값의 개수 : 2^n개

> n비트로 표현할 수 있는 부호 없는 정수의 범위 : 0 ~ 2^n -1

> n비트로 표현할 수 있는 부호 잆는 정수의 범위 : -2^n-1 ~ 2^n-1 -1

 

 

2.2 상수와 리터럴(constant & literal)

 

- 변수(variable) : 하나의 값을 저장하기 위한 공간 > 변경 o

- 상수(constant) : 한 번만 값을 저장 가능한 변수 > 변경 x

- 리터럴(literal) : 그 자체로 값을 의미하는 것 > 기존의 상수

>> 상수와 구분하기 위해 리터럴이라는 용어를 사용하는 것(상수는 값을 변경할 수 없기 때문에)

1
2
3
4
5
6
7
8
int score = 100;
 
    score = 200;
 
final int MAX = 100; // MAX는 상수
          MAX = 200; // 에러
    char ch = 'A';
String str = "abc";
cs
 
 
public class VarEx3 {
 
    public static void main(String[] args) {
        final int score = 100// final을 붙이면서 score가 상수가 됨 > 100을 다른 값으로 바꿀 수 없음
//        score = 200; 
        
        System.out.println(score);
    }
}
cs

 

* 리터럴의 타입과 접미사

- 모든 리터럴에도 타입이 있음

 

* 리터럴의 종류

- 논리형 : false, true / 접미사 > 없음

- 정수형 : 123, 0b0101, 077, 0xFF, 100L / 접미사 > L

- 실수형 : 3.14, 3.0e8, 1.4f, 0x1.0p-1 / 접미사 > f, d

- 문자형 : 'A', '1', '\n' / 접미사 > 없음

- 문자열 : "ABC, "123", "A", "true" / 접미사 > 없음

(접미사는 대소문자 구분하지 않음)

 

* 예시

boolean power = true;

char ch = 'A';

String str = "ABC";

 

byte b = 127; > int 타입 

byte b = 128; // 에러 (크기를 넘어섬)

 

int i = 100; // 10진수

int oct = 0100; // 8진수

int hex - 0x100; // 16진수

 

long 1 = 10_000_000_000L; // L 생략불가

long 1 = 100L; // OK L 생략가능

float f = 3.14f; // f 생략불가

double d = 3.14d; // L 생략가능

 

>> 변수의 값을 저장할 때는 기본적으로 변수의 타입과 리터럴의 타입이 일치해야 함!(일치하지 않아도 되는 경우도 있음)

 

10. → 10.0

.10 → 0.10

>> 두 리터럴 모두 소수점이 있기 때문에 실수형, 접미사가 안붙었기 때문에 double

10f → 10.0f

>> 실수형 접미사 f가 붙었기 때문에 실수형(float)

1e3 → 1000.0

>> 접미사가 없기 때문에 double 타입

:: 이처럼 실수형 접미사에는 f,d 외에도 리터럴의 소수점이나 10의 n제곱을 의미하는 e가 포함되면 실수형 리터럴이 됨

 

 

* 변수와 리터럴의 타입 불일치

① 범위가 '변수 > 리터럴'인 경우, OK

1
2
3
int i = 'A' ; // int > char
long l = 123; // long > int
double d = 314f; // double > float
cs

② 범위가 '변수<리터럴'인 경우, 에러

1
2
3
int i = 30_0000_0000; // int의 범위(+-20억) 벗어남
long l = 3.14f; // long < float
float f = 3.14; // float < double
cs

③ byte, short 변수에 int 리터럴 저장가능

1
2
byte b = 100; // OK. byte의 범위(-128~127)에 속함
byte b = 128; // 에러, byte의 범위를 벗어남
cs
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
 
public class VarEx3 {
 
    public static void main(String[] args) {
        final int score = 100// final을 붙이면서 score가 상수가 됨 > 100을 다른 값으로 바꿀 수 없음
//        score = 200; 
        boolean power = true;
        
        byte b = 127// -128~127
        
        int oct = 010// 8진수, 10진수로 8
        int hex = 0x10// 16진수, 10진수로 16
        System.out.println(oct); // println은 값을 10진수로 출력, 접두사와 접미사는 출력 x
        System.out.println(hex); // 8진수나 16진수로 출력하려면 printf라는 메서드 사용해야 함
        
        long l = 1000_000_000; // 백억이면 int 타입을 벗어남, 끝에 L을 붙여서 long타입 리터럴로 만들어야함
        
        float f = 3.14f; // 접미사 f 지우면 에러
        double d = 3.14d; // 접미사 d 지울 수 있음, 접미사 f 올 수 있음(float보다 넓어서)
        System.out.println(10.);
        System.out.println(.10);
        System.out.println(10f);
        System.out.println(1e3); // 값이 출력될 때 접미사는 출력되지 않음
    }
}
cs

 

* 문자 리터럴과 문자열 리터럴

- 문자 리터럴 :  'A'와 같이 작은 따옴표로 문자 하나를 감싼 것 > char

- 문자열 리터럴 : 두 문자 이상의 문자를 큰 따옴표로 감싼 것 > String

>> 문자열 리터럴은 "" 안에 아무 문자도 넣지 않는 것을 허용, 이것을 빈 문자열(empty string)이라고 함

     그러나, 문자 리터럴은 '' 안에 반드시 하나의 문자가 있어야 함

 

문자열 + any type → 문자열 + 문자열   문자열

any type + 문자열   문자열 + 문자열   문자열

 

1
2
3
4
5
6
7
8
9
10
11
12
13
char ch = 'J'; // char ch = 'Java'; 이렇게 할 수 없다.
String name = "Java"; // 변수 name에 문자열 리터럴 "Java"를 저장
 
String str = ""; / OK. 내용이 없는 빈 문자열 > 원래는 String이 클래스라 new가 필요하지만 없는 것도 허용
char ch = ''; // 에러. '' 안에 반드시 하나의 문자가 필요
char ch = ''; // OK. 공백 문자(black)로 변수 ch를 초기화
 
String name = new String("Java"); // String 객체를 생성
 
String name = "Ja" + "va"; // name은 "Java" 
String str = name + 8.0; // str은 "Java8.0" 
// 덧셈 연산자는 피연산자가 모두 숫자일 때는 두 수를 더하지만, 
// 피연산자 중 어느 한 쪽이 String이면 나머지 한 쪽을 먼저 String으로 변환한 다음 두 String을 결합
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
public class StringEx_ {
 
    public static void main(String[] args) {
        String name = "Ja" + "va";
        String str = name+ 8.0;
        
        System.out.println(name);
        System.out.println(str);
        System.out.println(7 + " ");
        System.out.println(" " + 7);
        System.out.println(7 + "");
        System.out.println("" + 7);
        System.out.println("" + "");
        System.out.println(7 + 7 + "");
        System.out.println("" + 7 + 7);
 
    }
 
}
 
cs
더보기

(결과)

Java
Java8.0

 7
7
7

14
77

 

 

2.3 형식화된 출력 - printf()

 

- println()의 단점 : 출력형식 지정불가

① 실수의 자리수 조절불가 - 소수점 n자리만 출력하려면?

System.out.println(10.0/3); // 3.33333...

1
2
3
4
5
6
7
8
9
10
11
 
public class PrintEx1 {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(10/3); // 정수/정수 = 정수
        System.out.println(10.0/3); // 답을 실수로 얻으려면 몫, 나누는 수 중 하나는 실수여야 함
    }
 
}
 
cs
더보기

(결과)

3

3.3333333333333335

②10진수로만 출력된다. - 8진수, 16진수로 출력하려면? > 지시자에 따라 달라짐

System.out.println(0x1A); // 26 > 10진수

▶printf()로 출력형식 지정가능

System.out.printf("%.2f", 10.0/3); // 3.33 

> %.2f : 소수점 둘째자리

System.out.printf("%d", 0x1A); // 26

> %d : 10진수

System.outprintf("%X", 0x1A); // 1A

> 16진수

 

* printf()의 지시자

  지시자 설명
정수  %b 불리언(boolean) 형식으로 출력
%d 10진(demical) 정수의 형식으로 출력
%o 8진(octal) 정수의 형식으로 출력
%x, %X 16진(hexa-decimal) 정수의 형식으로 출력
실수 %f 부동 소수점(floating-point)의 형식으로 출력
%e, %E 지수(exponent) 표현식의 형식으로 출력
문자 %c 문자(character)로 출력
%s 문자열(string)으로 출력

System.out.printf("age:%d year:%d\n, 14, 2017);

> "age:14 year:2017\n"이 화면에 출력된다.

 

System.out.printf("age:%d", age); // 출력 후 줄바꿈을 하지 않는다.

System.out.printf("age:%d%n", age); // 출력 후 줄바꿈을 한다.

 

① 정수를 10진수, 8진수, 16진수로 출력

System.out.printf("%d", 15) // 15 10진수 →  decimal

System.out.printf("%o", 15) // 17 8진수 →  octal

System.out.printf("%d", 15) // f 6진수 →  hexa

System.out.printf("%s", Integer.toBinaryString(15); // 1111 2진수

② 8진수와 16진수에 접두사 붙이기 > 접두사도 나오게 하려면 '#' 붙이기

System.out.printf("%#o", 15) // 017

System.out.printf("#x", 15) // 17 8진수 →  0xf

System.out.printf("%#x", 15) // f 6진수 →  0XF

③실수 출력을 위한 지시자 %f - 지수형식(%e), 간략한 형식(%g)

float f = 123.4567890f;

System.out.printf("%f", f); // 123.456787 > 소수점 아래 6자리

System.out.printf("%e", f); // 1.234568e+02 > 지수형식

System.out.printf("%g", 123.456789); // 123.457 > 간략한 형식

System.out.printf("%g", 0.00000001); // 1.00000e-8 > 간략한 형식

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
public class PrintEx1 {
 
    public static void main(String[] args) {
        
        System.out.printf("%d%n"15);
        System.out.printf("%#o%n"15);
        System.out.printf("%#x%n"15);
        System.out.printf("%s", Integer.toBinaryString(15));
        
        float f = 123.4567890f;
        System.out.printf("%f%n", f);
        System.out.printf("%e%n", f);
        System.out.printf("%g%n", f);
        
    }
 
}
cs

 

- %전체자리.소수점아래자리f

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
public class PrintEx1 {
 
    public static void main(String[] args) {
        
    System.out.printf("[%5d]%n"1234567);
    System.out.printf("[%-5d]%n"10);
    System.out.printf("[%05d]%n"10);
    
    double d = 1.23456789;
    System.out.printf("%.6f%n", d);
    
    System.out.printf("[%s]%n""www.codechobo.com");    
    System.out.printf("[%20s]%n""www.codechobo.com");    
    System.out.printf("[%-20s]%n""www.codechobo.com");    
    System.out.printf("[%.10s]%n""www.codechobo.com");    
    }
 
}
 
cs
더보기

(결과)

[1234567]
[10   ]
[00010]
1.234568
[www.codechobo.com]
[   www.codechobo.com]
[www.codechobo.com   ]
[www.codech]

 

 

2.4 화면에서 입력받기 - Scanner

 

- Scanner란?

: 화면으로부터 데이터를 입력받는 기능을 제공하는 클래스

- Scanner를 사용하려면...

①import문 추가

import java.util.*;

②Scanner객체의 생성

Scanner scanner = new Scanner (System.in);

③Scanner객체를 사용

int num = scanner.nextInt(); // 화면에서 입력받은 정수를 num에 저장

String input = scanner.nextLine(); // 화면에서 입력받은 내용을 input에 저장

int num = Integer.paraseInt(input); // 문자열(input)을 숫자(num)로 변환

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.util.*// 1. import문 추가
 
public class ScanfEx1 {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        // 2. Scanner클래스의 객체 생성
        Scanner scanner = new Scanner(System.in);
        
        int num = scanner.nextInt();
        int num2 = scanner.nextInt();
        System.out.println(num);
        System.out.println(num2);
        
    }
 
}
cs
더보기

(결과)

100 200 < 입력
100
200