[Chapter 2] 변수(Variable)_2

slchoi·2022년 1월 3일
0

자바의 정석

목록 보기
4/19
post-thumbnail

'자바의 정석 3rd Edition'을 공부하며 정리한 내용입니다.

2. 변수의 타입


  • 자료형(data tpye): 값(data)의 종류(type)에 따라 값이 저장될 공간의 크기와 저장형식을 정의한 것
    • 종류: 문자형(char), 정수형(byte, short,int, long), 실수형(float, double) 등
  • 변수를 선언할 때는 저장하려는 값의 특성을 고려해 가장 알맞은 자료형을 변수의 타입으로 선택

기본형과 참조형

  • 기본형 변수: 실제 값(data)를 저장
    • 종류: 논리형(boolean), 문자형(char), 정수형(byte, short, int, long), 실수형(float, double)
  • 참조형 변수: 어떤 값이 저장되어 있는 주소(memory address)를 값으로 가짐
    • 메모리 주소: 메모리에는 1 byte단위로 일련번호가 붙어있는데, 이 번호를 메모리 주소 또는 주소라고 함. 객체의 주소는 객체가 저장된 메모리 주소를 의미
    • 종류: 8개의 기본형을 제외한 나머지 타임
    • 참조형 변수를 선언할 때는 변수의 타입으로 클래스의 이름을 사용. 클래스의 이름이 참조변수의 타입이 됨. 새로운 클래스를 작성한다는 것은 새로운 참조형 변수를 추가하는 것
    • 참조형 변수 선언 방법: 기본형 변수와 같이 변수 이름 앞에 타입을 적어주는데 참조변수의 타입은 클래스의 이름
    클래스이름 변수이름; // 변수의 타입이 기본형이 아닌 것들은 모두 참조 변수
    • 참조 변수는 null 또는 객체의 주소를 값으로 가지며 참조변수의 초기화는 아래와 같음
    Date today = new Date() // Date 객체를 생성해서, 그 주소를 today에 저장
  • 자바는 참조형 변수 간의 연산을 할 수 없으므로 실제 연산에 사용되는 것은 모두 기본형 변수

참고) 자료형(data type) vs 타입(type)

  • 기본형은 저장할 값(data)의 종류에 따라 구분되므로 기본형의 종류를 얘기할 때는 '자료형(data type)'이라는 용어를 사용
  • 참조형은 항상 '객체의 주소(4 byte 정수)'를 저장하므로 값(data)이 아닌, 객체의 종류에 의해 구분되므로 참조형 변수의 종류를 구분할 때는 '타입(type)'이라는 용어를 사용
  • 타입(type)이 자료형(data type)을 포함하는 보다 넓은 의미의 용어이므로 굳이 구분하지 않아도 됨

2.1 기본형(primitive type)

종류/크기1 byte2 byte4 byte8 byte
논리형boolean
문자형char
정수형byteshortintlong
실수형floatdouble
  • 논리형(boolean)
    • true와 false 중 하나의 값을 가지며 조건식과 논리적 계산에 사용
    • 다른 기본형과의 연산이 불가능. boolean을 제외한 나머지 7개의 기본형은 서로 연산과 변환이 가능
  • 문자형(char)
    • 문자를 저장하는데 사용되며 변수에 하나의 문자만 저장할 수 있음
    • 내부적으로 정수(유니코드)로 저장하기 때문에 정수형과 다르지 않으며, 정수형 또는 실수형과 연산도 가능
  • 정수형(byte, short, int, long)
    • 주로 int를 사용(CPU가 가장 효율적으로 처리할 수 있는 타입). byte는 이진 데이터를 다룰 때 사용되며, short는 C언어와의 호환을 위해 추가됨
    • 효율적인 실행보다 메모리를 절약하려면 byte나 short를 선택
    • int 타입은 대략 10자리 수의 값을 저장할 수 있음. 7~9자리의 수를 계산할 때는 넉넉하게 long 타입(약 19자리)로 선언하는 것이 좋음
  • 실수형(float, double)
    • 실수를 저장하는데 사용. 주로 double를 사용함
    • 정수형과 저장형식이 달라서 같은 크기라도 훨씬 큰 값을 표현할 수 있으나 오차가 발생할 수 있다는 단점이 있음. 따라서 정밀도가 중요!
      • 정밀도가 높을수록 발생할 수 있는 오차의 범위가 줄어듦. float이 정밀도는 7자리인데, 이것은 10진수로 7자리의 수를 오차없이 저장할 수 있다는 것을 의미
    • float는 큰 값을 저장할 수 있지만, 정밀도가 7자리 밖에 되지 않으므로 높은 정밀도가 필요한 경우에는 변수 타입으로 double을 선택

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

1. 상수(constant)

  • 값을 저장할 수 있는 공간 but 한 번 값을 저장하면 다른 값으로 변경 불가
  • 상수 선언 방법은 변수와 동일. 변수의 타입 앞에 키워드 'final'을 붙여주면 됨
final int MAX_SPEED = 10 // 상수 MAX_SPEED를 선언 & 초기화
  • 상수는 반드시 선언과 동시에 초기화해야 하며, 그 후부터는 상수의 값을 변경할 수 없음
final int MAX_SPEED;		// 에러. 상수는 선언과 동시에 초기화해야 함
final int MAX_VALUE = 100;	// OK
MAX_VALUE = 200;		// 에러. 상수의 값은 변경할 수 없음
  • 상수의 이름은 모두 대문자로 하는 관례. 여러 단어로 이루어져 있는 경우 '_'로 구분

2. 리터럴(literal)

  • 12, 133, 3.14, 'A'와 같은 값들이 '상수'인데, 프로그래밍에서는 상수를 '값을 한 번 저장하면 변경할 수 없는 저장공간'으로 정의하였기 때문에 이와 구분해 상수를 다른 이름으로 불러야 했음
  • 따라서 상수 대신 리터럴이라는 용어를 사용

변수(variabl) 하나의 값을 저장하기 위한 공간
상수(costant) 값을 한번만 저장할 수 있는 공간
리터럴(literal) 그 자체로 값을 의미하는 것

3. 상수가 필요한 이유

int triangleArea = (20 *10) / 2 ; 	// 삼각형의 면적을 구하는 공식
int rectangleArea = 20 * 10 ;		// 사각형의 면적을 구하는 공식
  • 위 코드에서 10과 20이 아닌 다른 값을 이용해 결과를 얻고 싶다면 여러 곳을 수정해야 함
final int WIDTH = 20;	//폭
final int HEIGHT = 10	// 높이

int triangleArea = (WIDTH *HEIGHT) / 2 ; 	// 삼각형의 면적을 구하는 공식
int rectangleArea = WIDTH * HEIGHT ;		// 사각형의 면적을 구하는 공식
  • 이전 코드에 비해 면적을 구하는 공식의 의미가 명확해짐

  • 다른 값으로 계산할 경우에도 여러 곳을 수정할 필요없이 상수의 초기화만 다른 값으로 해주면 됨

  • 상수는 리터럴에 '의미있는 이름'을 붙여 코드의 이해와 수정을 쉽게 만듦

4. 리터럴의 타입과 접미사

종류접미사
논리형없음
정수형L
실수형f, d
문자형없음
문자열없음
  • 정수형과 실수형에는 여러 타입이 존재하므로 리터럴에 접미사를 붙여 타입을 구분
  • 정수형인 경우, long 타입의 리터럴에 접미사 'l' 또는 'L'을 붙이고, 접미사가 없으면 int 타입의 리터럴
    • byte와 short 타입의 리터럴은 별도로 존재하지 않으며 byte와 short 타입의 변수에 값을 저장할 때는 int 타입의 리터럴을 사용
  • 10진수 외에도 2, 8, 16진수로 표현된 리터럴을 변수에 저장할 수 있으며, 16진수라는 것을 표시하기 위해 리터럴 앞에 접투사 '0x' 또는 '0X'를, 8진수의 경우에는 '0'을 붙임
  • 실수형에서는 float 타입의 리터럴에 접미사 'f' 또는 'F'를 붙이고, double 타입의 리터럴에는 접미사 'd' 또는 'D'를 붙임
    • 정수형에서는 int가 기본 자료형인 것처럼 실수형에서는 double이 기본 자료형이라서 접미사 'd'는 생략이 가능
  • 리터럴에 소수점이나 10의 제곱을 나타내는 기호 E 또는 e, 그리고 접미사 f,F,d,D를 포함하고 있으면 실수형 리터럴로 간주

5. 타입의 불일치

  • 리터럴의 타입은 저장될 변수의 타입과 일치하는 것이 일반적이지만, 타입이 달라도 저장범위가 넓은 타입에 좁은 타입의 값을 저장하는 것은 혀용
int    i = 'A'	   // OK. 문자 'A'의 유니코드인 65가 변수 i에 저장됨
long   l = 123;	   // OK. int보다 long 타입이 더 범위가 넓음
double d = 3.14f   // OK. float보다 double 타입이 더 범위가 넓음
  • 리터럴의 값이 변수의 타입의 범위를 넘어서거나, 리터럴의 타입이 변수의 타입보다 저장범위가 넓으면 컴파일 에러 발생
int   i = 0x123456789;	// 에러. int 타입의 범위를 넘는 값을 저장
float f= 3.14		// 에러. float 타입보다 double 타입의 범위가 넓음
  • byte와 short 타입의 리터럴은 따로 존재하지 않으므로 int 타입의 리터럴을 사용. 단, short 타입의 변수가 저장할 수 있는 범위에 속한 것이어야 함
byte  b = 65;		// OK. byte 타입에 저장 가능한 범위의 int 타입 리터럴
short s = 01234;	// OK. short 타입에 저장 가능한 범위의 int 타입 리터럴

6. 문자 리터럴과 문자열 리터럴

  • 문자 리터럴: 'A'와 같이 작은 따옴표로 문자 하나를 감싼 것
  • 문자열 리터럴: 두 문자 이상을 큰 따옴표로 감싼 것
char	ch = 'J' ;
String  name = "JAVA"
  • char 타입의 변수는 단 하나의 문자만 저장. 문자열을 저장하기 위해서는 String 타입을 사용
  • 문자열 리터럴은 ""안에 아무런 문자도 넣지 않는 것을 허용 => 빈 문자열(empty string)
  • 문자 리터럴은 반드시 ''안에 하나의 문자가 있어야 함
  • 원래 String은 클래스이므로 객체를 생성하는 연산자 new를 사용해야 하지만 위와 같은 표현도 허용
String name = "JA" + "VA";
String str = name + 8.0;
  • 덧셈 연산자를 이용해 문자열을 결합할 수 있음
    • 덧셈 연산자는 피연산자가 모두 숫자일 때는 두 수를 더하지만, 피연산자 중 어느 한쪽이 String이면 나머지 한 쪽을 먼저 String으로 변환한 다음 두 String을 결합
    • 기본형과 참조형 구별 없이 어떤 타입의 변수도 문자열과 덧셈연산을 수행하면 그 결과는 문자열이 됨
    • 덧셈 연산자는 왼쪽에서 오른쪽의 방향으로 연산을 수행하기 때문에 결합순서에 따라 결과가 달라짐
    • 기본형 타입의 값을 문자열로 변환할 때 빈 문자열("")을 더해주면 됨

2.3 형식화된 출력 - printf()

  • println()은 사용하기엔 편하지만 변수의 값을 그대로 출력하므로, 값을 변환하지 않고는 다른 형식으로 출력할 수 없음
  • printf()는 '지시자(specifier)'를 통해 변수의 값을 여러 가지 형식으로 변환하여 출력
    • 지시자(specifier)은 값을 어떻게 출력할 것인지를 지정해주는 역할
      • 정수형 변수에 저장된 값을 10진 정수로 출력할 때는 지시자 '%d'를 사용
      • 변수의 값을 지정된 형식으로 변환해서 지시자 대신 넣음
System.out.printf("age: %d", age);
-> System.out.printf("age: %d", 14);
-> System.out.printf("age: 14");	// "age: 14"가 화면에 출력
  • 출력하려는 값이 2개라면, 지시자도 2개를 사용해야하며 출력될 값과 지시자의 순서는 일치해야 함 (개수 제한 없음)
  • printf()println()과 다르게 출력 후 줄바꿈을 하지 않음. 줄바꿈을 하려면 지시자 '%n'을 넣어줘야 함
  • 자주 사용되는 지시자 (지시자 전체 목록은 Java API에서 Formatter 클래스를 찾으면 됨)
지시자설명
%b불리언(boolean) 형식으로 출력
%d10진(decimal) 정수의 형식으로 출력. C언어와 다르게 char 타입은 사용 불가
%o8진(octal) 정수의 형식으로 출력
%x, %X16진(hexa-decimal) 정수의 형식으로 출력
%f부동 소수점(floating-point)의 형식으로 출력. 소수점 아래 6자리까지만 출력. 자리수 지정 가능
%e, %E지수(exponent) 표현식의 형식으로 출력
%c문자(character)로 출력
%s문자열(string)로 출력
  • 10진수를 2진수로 출력해주는 지시자는 없기 때문에, 정수를 2진 문자열로 변환해주는 Integer.toBinarySting(int i)를 사용해야 함

2.4 화면에서 입력받기 - Scanner

  • Scanner 클래스를 사용하려면 한 문장을 추가해줘야 함
import java.util.*;	// Scanner 클래스를 사용하기 위해 추가
  • Scanner 객체 생성
Scanner scanner = new Scanner(System.in);	// Scanner 클래스의 객체를 생성
  • nextLine()이라는 메서드를 호출하면, 입력 대기 상태에 있다가 입력을 마치고 Enter를 누르면 입력한 내용이 문자열로 반환됨
String input = scanner.nextLine();	// 입력받은 내용을 input에 저장
int num = Integer.parseInt(input);	// 입력받은 내용을 int 타입의 값으로 변환
  • Scanner 클래스에는 nextInt(), nextFloat()와 같이 변환없이 숫자로 바로 입력받을 수 있는 메서드가 있고, 이 메서드를 사용하면 문자열을 숫자로 변환해주지 않아도 됨
int num = scanner.nextInt();	// 정수를 입력받아서 변수 num에 저장
  • 위의 메서드는 화면에서 연속적으로 값을 입력받아 사용하기 어렵기 때문에 모든 값을 nextLine()으로 입력받아 적절히 변환하는 것이 더 나음
  • 숫자가 아닌 문자 또는 기호를 입력하면, 입력받은 문자열을 숫자로 변환하는 과정인 Integer.parseInt()에서 에러가 발생. 공백을 입력하지 않도록 주의!
profile
예비 백엔드 개발자

0개의 댓글