1. 변수와 상수

1.1 변수란?

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

1.2 변수의 선언과 초기화

int age; - 변수를 선언하면, 메모리의 빈 공간에 '변수타입'에 알맞은 크기의 저장 공간이 확보되고, 이 저장공간은 '변수이름'을 통해 사용 가능

변수의 초기화
변수를 '초기화(initialization)'해야 함 - 메모리는 여러 프로그램이 공유하는 자원이므로 전에 다른 프로그램에 의해 저장된 '알수 없는 값(쓰레기 값, garbage value)' 남아 있을 수 있기 때문
int age = 25; // 변수 age 선언, 25로 초기화
타입이 같은 경우는 콤마로 구분하기도 함 > int a, b;

1.3 변수의 명명규칙

'변수의 이름' 프로그래밍에서 사용하는 모든 이름을 '식별자(identifier)'라고 한다.

  1. 대소문자가 구분되며 길이에 제한이 없다. -True와 true는 서로 다른 것
  2. 예약어를 사용해선 안된다. - true는 예약어, True는 예약어 아님
  3. 숫자로 시작해서는 안된다. - top10는 허용, 7up는 안됨
  4. 특수문자는 '_'와 '$'만 허용 - $harp은 허용, S#arp는 안됨

    권장 규칙
    1.클래스 이름의 첫 글자는 항상 대문자 - 변수와 메서드의 이름의 첫 글자는 항상 소문자
    2.여러 단어로 이루어진 이름은 단어의 첫 글자를 대문자 - lastIndexOf, StringButer
    3.상수의 이름은 모두 대문자, 여러 단어로 이루어진 경우 '_'로 구분 - PI, MAX_NUMBER

2. 변수의 타입

자료형은 '기본형'과 '참조형'으로 나뉜다. 기본형 변수는 실제 값(data)를 저장, 참조형 변수는 어떤 값이 저장되어 있는 주소(memory address)를 값으로 가짐

기본형(primitive type)
-논리형(boolean), 문자형(char), 정수형(byte,short,int,long), 실수형(float,double) 계산을 위한 실제 값
참조형(reference type)
-객체의 주소를 저장한다. 8개의 기본형을 제외한 나머지 타입.
클래스 이름 변수이름; 변수의 타입이 기본형이 아닌 것들은 모두 참조 변수
-Date today = new Date(); //Date객체를 생성해서, 그 주소를 today에 저장

2.1 기본형(primitive type)

정수형(byte, short, int, long)의 경우 '-2의 n제곱근 - 1 ~ 2의 n제곱근 - 1(n은 bit수)
ex) int형의 경우 32bit(4 byte) 이므로 -2의31제곱근 ~ 2의31제곱근 -1

int타입의 변수는 대략 10자리 수(약 20억,의 값 저장 가능) 7~9자리의 수를 계산할 때는 넉넉하게 Long타입(약 19자리) 변수 선언하는게 좋음.
float은 값이 커서 오차가 발생 할 수 있어서 정밀도가 중요
float 정밀도 7자리, double 정밀도 15자리

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

상수 : 한번 값을 저장하면 다른 값으로 변경 할 수 없음.
final int MAXSPEED = 10; // 상수 MAX_SPEED를 선언 & 초기화
상수의 이름은 모두 대문자로 하는 것이 관례, 여러 단어로 이루어진 경우 '
'로 구분한다.

리터럴 : 상수를 '값을 한 번 저장하면 변경 할 수 없는 저장공간'으로 정의하였기 때문에 이와 구분하기 위해 상수를 다른 이름으로 불러야했음. 그래서 상수 대신 리터럴이란 용어 사용
리터럴은 기존에 알고 있는 '상수'의 다른 이름
ex) int year = 2014; 2014 > 리터럴
final int MAX_VALUE = 100; 100 > 리터럴

정수형의 경우, long타입의 리터럴에 접미사 'l'또는 'L'을 붙이고, 접미사가 없으면 Int타입의 리터럴

byte와 short타입의 리터럴은 별도로 존재하지 않으며 byte와 short타입의 변수에 값을 저장할 때는 int타입의 리터럴을 사용

10진수 외에도 2, 8, 16진수로 표현된 리터럴을 변수에 저장할 수 있으며, 16진수라는 것을 표시하기 위해 리터럴 앞에 접두사'0x' 또는 'OX'를, 8진수의 경우에는 '0'을 붙인다.
ex) int octNum = 010; // 8진수 10, 10진수로 8
int hexNum = 0x10; //16진수 10, 10진수로 16
int binNum = 0b10; //2진수로 10, 10진수로 2
float pi = 3.14f;
double rate = 1.618d; (d는 생략가능, double이 실수형에서 기본 자료형이기 때문이다)

문자 리터럴과 문자열 리터럴
'A' - 문자 리터럴, 두 문자 이상은 "문자열"

2.3 형식화된 출력 - printf()

printf()는 '지시자(specifier)'를 통해 변수의 값을 여러가지 형식으로 변환하여 출력하는 기능을 가지고 있다. 줄바꿈을 하지 않는다.

%b : 불리언 형식으로 출력
%d : 10진 정수의 형식으로 출력
%o : 8진 정수의 형식으로 출력
%x, %X : 16진정수의 형식으로 출력

System.out.printf("d = %14.10f%n", d); //전체 14자리중 소수점 아래 10자리
System.out.printf("[%s]\%n", url); //문자열의 길이 만큼 출력공간을 확보
System.out.printf("[%20s]\%n", url) //최소 20글자 출력 공간 확보(우측 정렬)
System.out.printf("[%-20s]\%n", url) //최소 20글자 출력 공간 확보(좌측 정렬)
System.out.printf("[%.8s]\%n", url) //왼쪽에서 8글자만 출력

3. 진법

3.1 10진법과 2진법

age 25 -> age 11001

3.2 비트(bit)와 바이트(byte)

한 자리의 2진수를 '비트'라고 한다. 1비트는 컴퓨터가 값을 저장 할 수 있는 최소 단위
1비트 > 8바이트

워드((word)는 CPU가 한 번에 처리 할 수 있는 데이터의 크기를 의미
n비트로 표현할수 있는 10진수
값의 개수 : 2의 n승
값의 범위 : 0 ~ 2의 n승 -1

3.3 8진법과 16진법

2진법은 0과 1만 사용함으로 값을 표현하면 자리수가 상당히 길어진다. 단점 보완을 위해 8진과 16진 사용
8진수는 2진수를 3자리, 16진수는 2진수 4자리를 각각 한자리로 표현 할 수 있다.
8진은 0~7의 숫자를 기호로 사용, 16진법은 0~9와 A~F까지 사용

3.4 정수의 진법 변환

10진수를 n진수로 변환 - 해당 진수로 나누고 값을 옆에 적는 것을 더 이상 나눌 수 없을 때까지 반복

3.5 실수의 진법 변환

  1. 10진 소수에 2를 곱한다.
  2. 위의 결과에서 소수부만 가져다가 다시 2를 곱한다.
  3. 1과 2의 과정을 소수부가 0이 될 때까지 반복한다.
    위의 결과에서 정수부만을 위에서 아래로 순서대로 적고 '0'을 앞에 붙이면 된다.

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

2의 보수법 : 어떤 수의 'n의 보수'는 더했을 때 n이 되는 수
7의 '10의 보수'는 3

4. 기본형

4.1 논리형 - boolean

true와 flase중 하나를 저장할 수 있으며 기본값(default)은 false이다.
대답(yes/no), 스위치(on/off)등의 논리 구현에 주로 사용
1bit만으로도 충분하지만, 자바에서는 데이터를 다루는 최소 단위가 byte이므로 boolean의 크기가 1byte이다.

4.2 문자형 - char

char ch = 'A';
변수에 '문자'가 저장되는 것 같지만, 사실은 문자가 아닌 '문자의 유니코드(정수)'가 저장 된다.
컴퓨터는 숫자밖에 모르기 때문에 모든 데이터를 숫자로 변환하여 저장하는 것이다.
문자'A'의 유니코드는 65이므로, 변수 ch에는 65가 저장된다.

char ch = 'A' ; //문자 'A'를 char타입의 변수 ch에 저장.
char ch = 65; // 문자의 코드를 직접 변수 ch에 저장

만일 어떤 문자의 유니코드를 알고 싶으면, char형 변수에 저장된 값을 정수형(int)로 변환하면 됨
int code = (int)ch;

tab : \t
backspace : \b
new line : \n
carriage return : \r
역슬래쉬 : \\
작은따옴표 : \'
큰따옴표 : \"
유니코드(16진수)문자 : \u유니코드 (예: char a='\u0041')

char타입의 크기는 2byte(=16 bit)이므로 2의 16제곱의 코드를 사용 할 수 있다.
에를들어 문자 'A'를 저장하면 10진수 65로 저장된다.

char 타입은 문자를 저장할 변수를 선언하기 위한 것이지만, 실제로 char타입의 변수에는 문자가 아닌 '문자의 유니코드(정수)'가 저장되고 표현형식 역시 정수형과 동일하다.
다음과 같이 변수 ch와 s에 'A'와 65를 저장하면 둘 다 2진수로 똑같은 값이 저장된다.
그런데 두 변수의 값을 출력해보면 결과가 다르다. println()은 변수의 타입이 정수형이면 변수에 저장된 값을 10진수로 해석하여 출력하고, 문자형이면 저장된 숫자에 해당하는 유니코드 문자를 출력하기 때문
System.out.println(ch); // A가 출력
System.out.println(s); //65가 출력
값의 타입을 알아야 정확한 해석이 가능.

4.3 정수형 - byte, short, int, long

byte(1) < short(2) < int(4) < long(8) (저장할수 있는 값의 범위, 단위는 byte)
n비트로 표현할 수 있는 정수의 개수 : 2의 n승 개
n비트로 표현할 수 있는 부호있는 정수의 범위 : -2의 n-1제곱 ~ 2의 n-1의 제곱 - 1

JVM의 피연산자 스택(operand strack)이 피연산자를 4 byte단위로 저장하기 때문에 크기가 4 byte보다 작은 자료형(byte,short)의 값을 계산할 때는 4 byte로 변환하여 수행된다. 그래서 오히려 int를 사용하는 것이 더 효율적이다.
정수형 변수를 선언할 때는 int 타입으로 쓰고, 범위가 약 20억을 넘어서는 수를 다룰땐 long 그리고 byte나 short은 성능보다 저장공간을 절약하는것이 중요할때 사용하자.

타입이 표현할 수 있는 값의 범위를 넘어서는 것을 오버플로우라고 한다.
최대값 + 1 -> 최소값
최소값 - 1 -> 최대값

부호없는 정수와 부호 있는 정수는, 오버플로우가 발생하는 시점이 다르다.
부호없는 정수는 2진수로'0000'이 될때, 부호있는 정수는 0에서 1될 때 오버플로우 발생

4.4 실수형 - float, double

실수형은 소수점도 표현해야 하므로 '얼마나 큰 값을 표현할 수 있는가'뿐만 아니라 '얼마나 0에 가깝게 표현할 수 있는가도' 중요하다.
실수형의 오버플로우는 무한대(infinity)

1.부호(Sign bit)
-S는 부호비트를 의미하며 1 bit이다. 이 값이 0이면 양수, 1이면 음수를 의미
2.지수(Exponent)
E는 지수를 저장하는 부분으로 float의 경우, 8bit의 저장공간을 갖는다.
3.가수(Mantissa)
-'M'은 실제 값인 기수를 저장하는 부분으로 flaot의 경우, 2진수 23자리를 저장할 수 있다.
float보다 2배의 정밀도를 갖는다.

5. 형변환

5.1 형변환(캐스팅, casting)이란?

연산을 수행하기전 타입을 일치시켜야 하는데, 변수나 리터럴의 타입을 다른 타입으로 변환하는 것을 '형변환(casting)'이라고 한다.

5.2 형변환 방법

(타입)피연산자
double d = 85.4;
int score = (int)d;

int -> char : (char)65 -> 'A'
char -> int : (int)'A' -> 65
float -> int : (int)1.6f -> 1
int -> float : (float)10 -> 10.0f

5.3 정수형 간의 형 변환

큰 타입에서 작은타입으로 변환은 값이 잘려나감으로 데이터 손실이 발생할 수 있다.
빈 공간은 0또는 1로 채운다. 원래는 값을 채우고 남은 빈 공간은 0으로 채우지만, 변환하려는 값이 음수인 경우엔 1로 채운다. 형변환 후 부호를 유지하기 위해

5.4 실수형 간의 형변환

작은타입에서 큰 타입으로 변환하는 경우, 빈공간을 0으로 채운다.
float타입의 범위를 넘는 값을 float로 형변환하는 경우는 +-무한대 또는 +-0을 결과로 얻는다.

5.5 정수형과 실수형 간의 형 변환

실수형은 정수형보다 훨씬 큰 저장범위를 갖기 때문에, 정수형을 실수형으로 변환하는 것은 별 무리가 없다.
정밀도의 제한으로 오차 발생의 주의해야 한다. int는 10자리의 정밀도, float은 7자리의 정밀도
10진수로 8자리 이상의 값을 실수형으로 반환할때는 float가 아닌 double로 형 변환해야 오차가 없다.
double은 약 15자리의 정밀도를 갖는다.

실수형을 정수형으로 변환하면, 실수형의 소수점 이하는 버려진다.
실수형을 정수형으로 형변환할 때 반올림이 발생하지 않는다.
1.666 -> 1

5.6 자동 형 변환

경우에 따라 편의상의 이유로 형변환을 생략할 수 있지만, 컴파일러가 생략된 형변환을 자동적으로 추가한다.

기존의 값을 최대한 보존 할 수 있는 타입으로 자동 형변환한다.
byte -> short,char -> int -> long -> float -> double

  1. boolean을 제외한 나머지 7개의 기본형은 서로 형변환이 가능하다.
  2. 기본형과 참조형은 서로 형변환 할 수 없다.
  3. 서로다른 타입의 변수간의 연산은 형변환을 하는 것이 원칙이지만,
    값의 범위가 작은 타입에서 큰 타입으로의 형변환은 생략할 수 있다.
profile
하루하루 최선을

0개의 댓글