[자바의 정석] Chapter02. 변수 Variable

Hyeonjun·2022년 9월 29일
0

자바의 정석

목록 보기
2/7
post-thumbnail

1. 변수 (variable)

“값”을 잘 다루는 것은 중요한 프로그래밍 능력 중 하나.

1.1 변수(variable)란?

단 하나의 값을 저장할 수 있는 메모리 공간

  • 이 공간에 저장된 값이 변경될 수 있기 때문에 ‘변수’라는 이름을 사용

1.2 변수의 선언과 초기화

변수의 선언

int age;

  • 변수타입 int
    • 변수에 저장될 값이 어떤 타입인지 지정하는 것.
    • 자바에는 정수형, 실수형, 문자형 등 타입을 제공
  • 변수이름 age
    • 변수에 붙인 이름
    • 메모리 공간에 이름을 붙여주는 것.
      • 그 이름을 이용해 저장공간에 값을 저장하고, 저장된 값을 읽어오기도 할 수 있다.
    • 같은 이름의 변수가 여러개 존재하면 안된다.
      • 서로 구별할 수 있어야함.
  • 변수를 선언하면 메모리의 빈 공간에 변수타입에 맞는 크기의 저장 공간이 확보되고, 앞으로 이저장공간을 변수이름으로 사용할 수 있다.

변수의 초기화

변수를 사용하기 전에 처음으로 값을 저장하는 것

  • 변수를 선언한 이후부터는 변수를 사용할 수 있으나, 그 전에 반드시 변수를 초기화(initiaization)해야한다.
    • 메모리는 여러 프로그램이 공유하는 자원이므로 전에 다른 프로그램에 의해 저장된 알 수 없는 값(쓰레기값, garbage value)가 남아있을 수 있다.
  • 대입연산자 =를 이용해 변수에 값을 저장한다.
    • 오른쪽의 값을 왼쪽(변수)에 저장하라는 뜻.
  • 변수의 종류에 따라 변수의 초기화를 생략할 수 있는 경우도 있지만, 변수는 사용되기 전 적절한 값으로 초기화 하는 것이 좋다.
    • 지역변수는 반드시 초기화를 해야함.
    • 클래스변수와 인스턴스 변수는 초기화를 생략할 수 있다.
  • 변수에 저장된 값을 사용하려면 변수의 이름만 적어주면 된다.
  • 변수에 값을 저장하는 대입연산(=)은 우변의 모든 계산이 끝난 후에 제일 마지막에 수행된다.

두 변수의 값 교환하기

  • x의 값을 y에 저장하고, y의 값을 x에 저장하는 것으로는 두 값을 교환할 수 없다.
    • x의 값을 y에 저장하는 순간 y의 값은 사라지기 때문.
  • 하나의 변수를 더 선언하여 임시 저장소로 사용하면 된다.
    int x = 10;
    int y = 20;
    int temp;
    
    temp = x;
    x = y;
    y = temp;
    • 기본적인 swap 함수이다.

1.3 변수의 명명규칙

식별자 (Identifier)

  • 프로그래밍에서 사용하는 모든 이름
  • 같은 영역 내에서 서로 구분(식별)될 수 있어야한다.
  • 식별자 생성 규칙
    1. 대소문자가 구분되며 길이에 제한이 없다.
      • True와 true는 서로 다른 것으로 간주된다.
    2. 예약어를 사용해서는 안된다.
      • true는 예약어이기 때문에 사용할 수 없지만, True는 가능
    3. 숫자로 시작해서는 안된다.
      • top10은 허용, 7up은 허용되지 않는다.
    4. 특수문자는 _$만을 허용한다.
      • $harp은 허용되지만 S#arp는 허용되지 않는다.
  • 예약어는 키워드(keyword) 혹은 리저브드 워드(reserved word)라고 하는데, 프로그래밍의 구문에 사용되는 단어를 뜻한다.
    • 클래스나 변수, 메서드의 이름으로 사용할 수 없다.
  • 권장 규칙
    1. 클래스 이름의 첫 글자는 항상 대문자로 한다.
      • 변수와 매서드의 이름의 첫 글자는 항상 소문자로 한다.
    2. 여러 단어로 이루어진 이름은 단어의 첫 글자를 대문자로 한다.
    3. 상수의 이름은 모두 대문자로 한다. 여러 단어로 이루어진 경우 _로 구분한다.

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)

분류타입설명
논리형booleantrue와 false 중 하나를 값으로 가지며, 조건식과 논리적 계산에 사용된다.
문자형char문자를 저장하는데 사용되며, 변수에 하나의 문자만 저장할 수 있다.
정수형byte, short, int, long정수를 저장하는데 사용되며, 주로 int가 사용된다. byte는 이진 데이터를 다룰 때 사용되며, short는 C언어와의 호환을 위해 추가되었다.
실수형float, double실수를 저장하는데 사용되며, 주로 double이 사용된다.
  • 문자형인 char는 문자를 내부적으로 정수(유니코드)로 저장하기 때문에 정수형과 별반 다르지 않음.
    • 정수형 또는 실수형과 연산도 가능하다.
  • boolean은 다른 기본형과의 연산이 불가능하다.
  • int가 CPU가 가장 효율적으로 처리할 수 있는 타입이기 때문에 정수형 중 가장 보편적으로 사용.
    • 효율적인 실행보다 메모리를 절약하고 싶다면 byte나 short를 선택.
  • 정수형은 int, 실수형은 double이 기본 자료형이다.
  • 기본형의 종류와 크기
    1byte2byte4byte8byte
    논리형boolean
    문자형char
    정수형byteshortintlong
    실수형floatdouble
  • 기본형의 크기와 범위
    자료형저장가능한 값의 범위크기(bit)크기(byte)
    booleanfalse, true81
    char'\u0000’ ~ ‘uffff’162
    byte-128 ~ 127 (-2^7 ~ 2^7 - 1)81
    short-32768 ~ 23767 (-2^15 ~ 2^15 - 1162
    int-2_147_493_648 ~ 2_147_483_647(약 20억)324
    long-2^63 ~ 2^63 - 1648
    float1.4E-45 ~ 3.4E38 (1.410^-45 ~ 3.4 10^38324
    double4.910^0324 ~ 1.8 10^308648
  • 실수형과 정수형의 저장형식은 다르다.
    • 더 큰 값을 표현할 수 있으나 오차가 발생할 수 있다.
    • float의 정밀도는 7자리
    • double의 정밀도는 15자리
  • float는 접미사나 정밀도 등 신경쓸 것이 많다. 이런 것들이 귀찮다면 그냥 double을 이용하자.

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

상수(constant)

  • 값을 저장할 수 있는 공간이지만 변수와 달리 한번 값을 지정하면 다른 값으로 변경할 수 없다.
  • 변수의 타입 앞에 final을 붙여준다.
  • 상수는 반드시 선언과 동시에 초기화해야 하며, 그 후부터는 상수의 값을 변경하는 것이 허용되지 않는다.

리터럴(literal)

  • 상수를 값을 한 번 저장하면 변경할 수 없는 저장공간으로 정의하였기 때문에 이와 구분하기 위해 상수(를 다른 이름으로 불러야 한다.
  • 변수: 하나의 값을 저장하기 위한 공간
  • 상수: 값을 한번만 저장할 수 있는 공간
  • 리터럴: 그 자체로 값을 의미

상수가 필요한 이유

  • 리터럴을 사용하면 될텐데, 왜 굳이 상수를 사용하는가?
  • 상수는 리터럴에 의미있는 이름을 붙여서 코드의 이해와 수정을 쉽게 만든다.

리터럴의 타입과 접미사

  • 리터럴에도 타입이 있다.
  • 변수의 타입은 저장될 값의 타입(리터럴의 타입)에 의해 결정되므로, 만일 리터럴에 타입이 없다면 변수의 타입도 필요없을 것이다.
  • 정수형과 실수형에는 여러 타입이 존재하므로 리터럴에 접미사를 붙여 타입을 구분한다.
    • long: I / L
    • int: 접미사 없음.
    • 16진수: 0x / 0X
    • 8진수: 0
  • JDK1.7부터 정수형 리터럴의 중간에 구분자 _를 넣을 수 있게 되어 큰 숫자를 편하게 읽을 수 있다.
    • int MAX = 1_000_000_000;
  • 실수형 리터럴에는 접미사를 붙여 타입을 구분한다.
    • 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()의 지시자
    지시자설명
    %bboolean 형식으로 출력
    %d10진 형식으로 출력
    %ndn자리 정수로 출력 (앞에 space)
    %-ndn자리 정수로 출력하되, 빈 자리는 뒤에 출력
    %0ndn자리 정수로 출력하되, 빈 자리에 0 출력
    %o8진 형식으로 출력
    %x, %X16진 형식으로 출력
    %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진수로 변환

  • 2진수 to 8진수
    • 3자리씩 끊어서 바꿈.
  • 2진수 to 16진수
    • 4자리씩 끊어서 바꿈

3.4 정수의 진법 변환

알고리즘… 했잖아요…?

10진수를 n진수로 변환

  • 0보다 클 때까지 n으로 나누면서 나머지를 확인 후 반대로 읽음.

n진수를 10진수로 변환

  • 각 자리값과 자리수를 곱해 더함

실수의 진법 변환

10진 소수점수를 2진 소수점수로 변환

  • 정수부는 3.4와 같이.
  • 소수부는 반대로 2를 곱하면서 정수부를 아래로 적으면 됨.

2진 소수점수를 10진 소수점수로 변환

  • 각 자리값는 그대로이므로 자리수 * 자리값의 합

3.6 음수의 2진 표현 - 2의 보수법

  • 가장 첫번째 비트를 부호비트로 사용

2의 보수법

  • n의 보수는 더했을 때 n이 되는 수.
    • 7의 10의 보수는 3
  • 자리올림이 발생하고 0이 되는 수이기도 하다.
  • 대부분의 시스템에서 2의 보수ㅜ법으로 부호있는 정수를 표현한다.

음수를 2진수로 표현하기

  1. 10진 음의 정수의 절대값을 2진수로 변환한다.
  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개의 기본형은 서로 형변환이 가능하다.
  • 기본형과 참조형은 서로 형변환할 수 없다.
  • 서로 다른 타입의 변수간의 연산은 형변환을 하는 것이 원칙이지만, 값의 범위가 작은 타입에서 큰 타입으로의 형변환은 생략할 수 있다.
profile
더 나은 성취

0개의 댓글