학원 5일차 - Java
2021.04.02
(자료형)형변환, (Data)Type Casting
- 자료형을 변환시키는 기술
- int -> float
- double -> byte
- 코드가 유연해지는 장점이 있다.
암시적 형변환, 자동 타입 형변환
- 큰형 = 작은형 (작은형을 큰형에 대입)
- 100%안전 (값 손실이 일어나지 않아서)
byte -> short
byte -> int
byte -> long
short -> int
short -> long
int -> long
- = 연산자 -> 변수 = 값; (대입)
- LValue(변수) = RValue(상수, 변수)
- = 연산자는 반드시 LValue와 RValue의 자료형이 동일해야 한다. > 동일하지 않으면 복사를 못한다.(에러발생!!)
byte b1 = 10;
short s1;
//short = byte; 대입
//2byte = 1byte
//양쪽에 자료형이 동일하지 않은데 에러가 나지 않는이유?
//개발자가 모르게 형변환이 발생한다 > 암시적인 형변환, 자동 형변환
//s1 = b1; // 권장 -> 익숙함
//() : 형변환 연산자
//컴파일러가 컴파일을 할 때 윗줄을 현재줄과 같이 번역한다.
s1 = (short)b1; // 권장 -> 가독성 향상
System.out.println("복사본 : "+ s1);
b1 = Byte.MIN_VALUE;
s1 = b1;
System.out.println("복사본: "+ s1); //최소값
b1 = Byte.MAX_VALUE;
s1 = b1;
System.out.println("복사본: "+ s1); //최대값
long l1;
//long = byte
//4byte = 1byte
//***암시적 형변환 발생
l1 = b1;
l1 = (long)b1;
System.out.println("복사본 :" + l1);
명시적 형변환, 강제 타입 변환
- 작은형 = 큰형
- 경우에 따라 다르다 (작은형이 포함할 수 있는 원본이면 안전하고, 포함할 수 없는 원본이면 불완전하다.)
- 결론 : 굉장히 위험한 작업이다... 정신을 바짝 차려라!!!!... 틀리면 죽는다...왜냐면 에러메세지가 없다 > 근데 값이 이상하다..!!!!! -> 논리 오류)
컴파일 vs 런타임 (★★중요★★)
컴파일 : 실제 프로그램을 실행하는 것이 아니라, 단지 언어만 번역하는 작업만 한다. 단, 그 좌정 중에 문법이 유효한지 검사를 한다.
short s2 = 10;
byte b2;
//Type mismatch: cannot convert from short to byte
//b2 = s2;<- 컴파일 에러
b2 = (byte)s2;
System.out.println("복사본: " + b2);
s2 = 127;
b2 = (byte)s2;
System.out.println("복사본: " + b2);
//byte의 범위를 벗어나는 값을 대입 -> 값 손실이 일어남. -> 값이 불완전
s2 = 128;
//b2 = 128; <- 컴파일 에러
b2 = (byte)s2;
System.out.println("복사본: " + b2); //-128
s2 = 1000;
b2 = (byte)s2;
System.out.println("복사본: " + b2); //-24
s2 = 10000;
b2 = (byte)s2;
System.out.println("복사본: " + b2); //16
정리
-
암시적 형변환
- 왜 암시적? -> 개발자가 이 사실을 알던 모르던,, 결과는 안전하니까 ,, 생략가능
- short-> byte
-
명시적 형변환
- 왜 명시적? 이 작업은 잘못될 가능성이 존재한다. 개발자 너는 이 사실을 명시적으로 책임지고 직접 형변환을 해라 -> 너의 책임이다.!!
- 오버플로우(overFlow) or 언더플로우(underFlow) 발생
//은행 계좌 : 20억
int m1 = 2000000000;
//이체
short m2;
//사전체크 꼭 할 것!!!
m2 = (short)m1;
System.out.println("계좌잔고 : "+ m2);
실수형 형변환
- float, double
float f1 = 3.14F;
double d1;
//암시적 형변환
//8byte = 4byte
System.out.println(d1); // 복사본
float f2;
double d2 = 3.14;
//명시적 형변환
//4byte = 8byte
f2 = (float)d2;
System.out.println(f2);
//정수형 : byte, short, int, long -> int, long 사용
//실수형 : float , double -> double 사용(정밀도 때문)
//정수형 모든 상수는 무조건 int다.
//100L -> long
byte n1 = 100; //byte = int
//byte n1 = (byte)100; -> 명시적 형변환 안적어도 되는 이유? 예외로 해줌
short n2 = 100; //short = int // 명시적 형변환 예외해줌,,
int n3 = 100; //int = int
long n4 = 100; //long = int
- 정수 <->실수 형변환
//암시적 형변환
int a1;
float a2;
a1 = 100;
//float = int
//4byte = 4byte
a2 = a1;
System.out.println(a2);
//명시적 형변환
int a3;
float a4;
a4 = 100F;
//int = float
//4byte = 4byte
//int(+- 21억) = float(+- 무한대)
a3 = (int)a4;
System.out.println(a3);
a4 = 3.14F;
a3 = (int)a4;
System.out.println(a3); //3.14 -> 3 일부러 값을 버림
long a5;
float a6;
a5 = 10000000;
//float = long
//4byte = 8byte
//무한대 = +-922경
a6 = a5;
System.out.println(a6);
- 숫자 자료형의 크기 (★★중요★★)
byte(1) < short(2) < int(4) < long(8) <<<<< float(4) < double(8)
문자형 형변환
- char
- 문자형 -> 문자코드로 저장 -> char은 숫자자료형에 속한다. 단, 가감승제를 안하는 숫자형
- char를 정수로 형변환 할때는 반드시 int를 사용한다.(short(byte)를 사용하면 절대 안된다.
- char의 범위를 다 수용하지 못하기 때문에 유니코드를 전부 사용 할 수 없다. (★★중요★★)
//char = short
char c5;
short s5;
s5 = 97;
System.out.println(s5);
c5 = (char)s5;
System.out.println("c5");
//short = char
char c6;
short s6;
c6 = 'A';
s6 = (short)c6;
System.out.println(s6);
//char <-> int
System.out.println((int)'A');
System.out.println((int)'가');
System.out.println((short)'가'); //오버플로우 발생...!!!
나누기 연산자
System.out.println(a/b); //3 -> 몫 -> 정수 / 정수(소수 이하는 출력 x)
System.out.println(10.0/3.0); // -> 실수 / 실수
나누기 연산자
정수 / 정수 = 정수
정수 / 실수 = 실수
실수 / 정수 = 실수
실수 / 실수 = 실수
System.out.println(10 / 3); //3
System.out.println(10 / 3.0); //3.3333333333333335
System.out.println(10.0 / 3); //3.3333333333333335
System.out.println(10.0 / 3.0); //3.3333333333333335
System.out.println(a / (double)b); //3.3333333333333335
System.out.println((double)a / b); //3.3333333333333335
-
모든 산술 연산의 결과는 항상 자료형이 두 피연산자 중 더 큰 자료형으로 반환된다.
+(더하기) : 오버플로우 신경 쓸 것 (넘칠 것 같으면 더 큰 자료형으로 형변환해주자)
-(빼기): 오버플로우 신경 쓸 것
*(곱하기): 오버플로우 더욱 신경 쓸 것
/(나누기): 오버플로우 발생 x, 소수점 이하를 남길지 말지를 결정하자.
%(나머지) : 신경 x
System.out.println(10 / 3); // int / int = int
System.out.println(10 / 3.0); //int / double = double
System.out.println(10.0 / 3); //double / int = double
System.out.println(10.0 / 3.0); // double / double = double
int money1 = 2000000000;
int money2 = 1500000000;
//int + int = int ---> 오버플로우 발생. ----> 논리적 오류
System.out.println("잔액 : " + (money1 + money2)); //잔액 : -794967296
System.out.println("잔액 : " + (money1 + (long)money2)); //int + long = long (형변환)
비교연산자
- <, >, <=, >=, ==(같다, equal), !=(다르다. a<>b, not equal)
- 2항 연산자
- 피연산자는 모두 숫자형
- 연산의 결과가 항상 boolean(true, false)
a = 10;
b = 5;
System.out.println(a > b);
System.out.println(a >= b);
System.out.println(a < b);
System.out.println(a <= b);
System.out.println(a == b);
System.out.println(a != b);
//요구사항) num이 양수입니까?
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("숫자 입력: ");
int num = Integer.parseInt(reader.readLine());
System.out.println("결과 : " + (num > 0));
- (★★중요★★)문자열의 비교는 동등 비교만 가능하고, 연산자(==, !=)사용이 불가능하고 대신, equals()메소드를 사용해야한다.
String str1 = "홍길동";
String str2 = "홍길동";
String str3 = "아무개";
String str4 = "홍";
str4 = str4 + "길동";
System.out.println(str4);
System.out.println(str1 == str2);
System.out.println(str1 == str3);
System.out.println(str1 == str4);
System.out.println("-------equals()--------");
//문자열비교는 equals()메소드를 사용해야함..!!!!!!!!
System.out.println(str1.equals(str2)); //str1 == str2
System.out.println(str1.equals(str4)); //str1 == str4 //true
논리연산자
- &&(and), ||(or), !(not)
- 2항 연산자(&&, ||), 1항연산자(!)
- 피연산자를 반드시 boolean을 가진다.
- 연산 결과를 boolean으로 반환한다.
- 피연산자를 가지고 특정한 규칙에 따라 연산의 결과를 반환한다.
byte -> short
byte -> int
byte -> long
short -> int
short -> long
int -> long
byte b1 = 10;
short s1;
//short = byte; 대입
//2byte = 1byte
//양쪽에 자료형이 동일하지 않은데 에러가 나지 않는이유?
//개발자가 모르게 형변환이 발생한다 > 암시적인 형변환, 자동 형변환
//s1 = b1; // 권장 -> 익숙함
//() : 형변환 연산자
//컴파일러가 컴파일을 할 때 윗줄을 현재줄과 같이 번역한다.
s1 = (short)b1; // 권장 -> 가독성 향상
System.out.println("복사본 : "+ s1);
b1 = Byte.MIN_VALUE;
s1 = b1;
System.out.println("복사본: "+ s1); //최소값
b1 = Byte.MAX_VALUE;
s1 = b1;
System.out.println("복사본: "+ s1); //최대값
long l1;
//long = byte
//4byte = 1byte
//***암시적 형변환 발생
l1 = b1;
l1 = (long)b1;
System.out.println("복사본 :" + l1);
컴파일 vs 런타임 (★★중요★★)
컴파일 : 실제 프로그램을 실행하는 것이 아니라, 단지 언어만 번역하는 작업만 한다. 단, 그 좌정 중에 문법이 유효한지 검사를 한다.
short s2 = 10;
byte b2;
//Type mismatch: cannot convert from short to byte
//b2 = s2;<- 컴파일 에러
b2 = (byte)s2;
System.out.println("복사본: " + b2);
s2 = 127;
b2 = (byte)s2;
System.out.println("복사본: " + b2);
//byte의 범위를 벗어나는 값을 대입 -> 값 손실이 일어남. -> 값이 불완전
s2 = 128;
//b2 = 128; <- 컴파일 에러
b2 = (byte)s2;
System.out.println("복사본: " + b2); //-128
s2 = 1000;
b2 = (byte)s2;
System.out.println("복사본: " + b2); //-24
s2 = 10000;
b2 = (byte)s2;
System.out.println("복사본: " + b2); //16
암시적 형변환
- 왜 암시적? -> 개발자가 이 사실을 알던 모르던,, 결과는 안전하니까 ,, 생략가능
- short-> byte
명시적 형변환
- 왜 명시적? 이 작업은 잘못될 가능성이 존재한다. 개발자 너는 이 사실을 명시적으로 책임지고 직접 형변환을 해라 -> 너의 책임이다.!!
//은행 계좌 : 20억
int m1 = 2000000000;
//이체
short m2;
//사전체크 꼭 할 것!!!
m2 = (short)m1;
System.out.println("계좌잔고 : "+ m2);
float f1 = 3.14F;
double d1;
//암시적 형변환
//8byte = 4byte
System.out.println(d1); // 복사본
float f2;
double d2 = 3.14;
//명시적 형변환
//4byte = 8byte
f2 = (float)d2;
System.out.println(f2);
//정수형 : byte, short, int, long -> int, long 사용
//실수형 : float , double -> double 사용(정밀도 때문)
//정수형 모든 상수는 무조건 int다.
//100L -> long
byte n1 = 100; //byte = int
//byte n1 = (byte)100; -> 명시적 형변환 안적어도 되는 이유? 예외로 해줌
short n2 = 100; //short = int // 명시적 형변환 예외해줌,,
int n3 = 100; //int = int
long n4 = 100; //long = int
//암시적 형변환
int a1;
float a2;
a1 = 100;
//float = int
//4byte = 4byte
a2 = a1;
System.out.println(a2);
//명시적 형변환
int a3;
float a4;
a4 = 100F;
//int = float
//4byte = 4byte
//int(+- 21억) = float(+- 무한대)
a3 = (int)a4;
System.out.println(a3);
a4 = 3.14F;
a3 = (int)a4;
System.out.println(a3); //3.14 -> 3 일부러 값을 버림
long a5;
float a6;
a5 = 10000000;
//float = long
//4byte = 8byte
//무한대 = +-922경
a6 = a5;
System.out.println(a6);
byte(1) < short(2) < int(4) < long(8) <<<<< float(4) < double(8)
- char의 범위를 다 수용하지 못하기 때문에 유니코드를 전부 사용 할 수 없다. (★★중요★★)
//char = short
char c5;
short s5;
s5 = 97;
System.out.println(s5);
c5 = (char)s5;
System.out.println("c5");
//short = char
char c6;
short s6;
c6 = 'A';
s6 = (short)c6;
System.out.println(s6);
//char <-> int
System.out.println((int)'A');
System.out.println((int)'가');
System.out.println((short)'가'); //오버플로우 발생...!!!
System.out.println(a/b); //3 -> 몫 -> 정수 / 정수(소수 이하는 출력 x)
System.out.println(10.0/3.0); // -> 실수 / 실수
나누기 연산자
정수 / 정수 = 정수
정수 / 실수 = 실수
실수 / 정수 = 실수
실수 / 실수 = 실수
System.out.println(10 / 3); //3
System.out.println(10 / 3.0); //3.3333333333333335
System.out.println(10.0 / 3); //3.3333333333333335
System.out.println(10.0 / 3.0); //3.3333333333333335
System.out.println(a / (double)b); //3.3333333333333335
System.out.println((double)a / b); //3.3333333333333335
모든 산술 연산의 결과는 항상 자료형이 두 피연산자 중 더 큰 자료형으로 반환된다.
+(더하기) : 오버플로우 신경 쓸 것 (넘칠 것 같으면 더 큰 자료형으로 형변환해주자)
-(빼기): 오버플로우 신경 쓸 것
*(곱하기): 오버플로우 더욱 신경 쓸 것
/(나누기): 오버플로우 발생 x, 소수점 이하를 남길지 말지를 결정하자.
%(나머지) : 신경 x
System.out.println(10 / 3); // int / int = int
System.out.println(10 / 3.0); //int / double = double
System.out.println(10.0 / 3); //double / int = double
System.out.println(10.0 / 3.0); // double / double = double
int money1 = 2000000000;
int money2 = 1500000000;
//int + int = int ---> 오버플로우 발생. ----> 논리적 오류
System.out.println("잔액 : " + (money1 + money2)); //잔액 : -794967296
System.out.println("잔액 : " + (money1 + (long)money2)); //int + long = long (형변환)
a = 10;
b = 5;
System.out.println(a > b);
System.out.println(a >= b);
System.out.println(a < b);
System.out.println(a <= b);
System.out.println(a == b);
System.out.println(a != b);
//요구사항) num이 양수입니까?
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("숫자 입력: ");
int num = Integer.parseInt(reader.readLine());
System.out.println("결과 : " + (num > 0));
String str1 = "홍길동";
String str2 = "홍길동";
String str3 = "아무개";
String str4 = "홍";
str4 = str4 + "길동";
System.out.println(str4);
System.out.println(str1 == str2);
System.out.println(str1 == str3);
System.out.println(str1 == str4);
System.out.println("-------equals()--------");
//문자열비교는 equals()메소드를 사용해야함..!!!!!!!!
System.out.println(str1.equals(str2)); //str1 == str2
System.out.println(str1.equals(str4)); //str1 == str4 //true
boolean b1 = true;
boolean b2 = false;
boolean b3 = true;
boolean b4 = false;
System.out.println(b1 && b2); //true && false = false
System.out.println(b1 && b3); // true && true = true
System.out.println(b2 && b4); //false && false = false
System.out.println(b1 || b2); //true || false = true
System.out.println(b1 || b3); //true || true = true
System.out.println(b2 || b4); //false || false = false
//소개팅) 긴머리, 서울
String address = "서울";
String hair = "긴머리";
System.out.println(address.equals("서울") && hair.equals("긴머리"));
System.out.println(address.equals("서울") || hair.equals("긴머리"));
//1항 연산자 : 피연산자가 1개
System.out.println(!true);
System.out.println(!false);
boolean flag = true;
System.out.println(!flag);
대입연산자, 할당연산자
- =
- +=, -=, *=, /=, %= : 복합 대입 연산자
- LValue = RValue
int n = 10;
n = n + 1; //누적
System.out.println(n); //11
n += 1; //n = n + 1
System.out.println(n);
n = n + 5;
System.out.println(n);
n+=5;
System.out.println(n);
n +=123;
System.out.println(n);
n = 10;
n = n - 1;
n -=1;
System.out.println(n);
n = 10;
n = n * 2;
n *= 2;
System.out.println(n);
n = 10;
n = n / 2;
n /= 2;
System.out.println(n);
n = 10;
n = n % 3;
n %= 3;
System.out.println(n);
n = 10;
//-=, /=, %= 은 피연산자의 위치를 주의!!!!!
n = 20 - n;
n -= 20;// n = n-20
증감연산자
- ++(증가), --(감소)
- 1항 연산자
- 피연산자로 숫자
- 피연산자의 값을 +1, -1 누적시키는 연산자
- 연산자의 결과가 경우에 따라 달라진다.
- 연산자의 위치와 피연산자의 위치를 바꿀 수 있다.
- ++n : 전위(전치) 연산자. 연산자 우선 순위가 가장 높다.
- n++ : 후위(후치)연산자. 연산자 우선 순위가 가장 낮다.
- 연산자의 위치와 피연산자의 위치를 바꿀 수 있다.
n = 10;
n = n + 1; //11
n +=1; //12
++n; //13
n++;
System.out.println(n);
n = n - 1;
n -= 1;
--n;
n--;
System.out.println(n);
연산자우선순위
- 연산자들을 실행하는 순서
- 산술연산자 > 비교연산자 > 논리연산자 > 대입연산자
- 증감연산자>산술연산자 > 비교연산자 > 논리연산자 > 대입연산자 -> 전위 ++n
- 산술연산자 > 비교연산자 > 논리연산자 > 대입연산자 > 증감연산자 ->후위 n++
boolean result = 10 > 5 + 1 && 8 < 2 * 3;
//순서 어려우면 ()괄호쳐서 가독성 높이기
//boolean result = (10 > (5 + 1)) && (8 < (2 * 3));
//연산순서
//boolean result = 10 > 6 && 8 < 6;
//boolean result = true && false;
//boolean result = false;
int num = 10;
int sum = 0;
sum = 20 + ++num; //sum = 20 + 11; -> 31
System.out.println(sum); //31
num = 10;
sum = 0;
sum = 20 + num++; // ((sum = (20+num))++)
System.out.println(sum); //30
System.out.println(num); //11
//증감연산자는 다른 연산자와 같은 문장에 작성하지 말 것!!!!!!!
num = 10;
sum = 0;
//sum = 20 + ++num;
++num;
sum = 20 + num;
System.out.println(sum);
System.out.println(num);
num = 10;
sum = 0;
//sum = 20 + num++;
sum = 20 + num;
num++;
System.out.println(sum);
System.out.println(num);
//?
int o = 10;
System.out.println(--o-o--);
조건연산자
- A ? B :c
- 3항 연산자
- A : 조건(boolean)
- B,C : 상수, 변수, 연산식 -> 값 -> 연산의 결과값
- B와 C는 반드시 바료형이 동일해야 한다.
- if문 사용
System.out.println(1 + 2);
System.out.println(true ? "참" : "거짓");
System.out.println(false ? "참" : "거짓");
//사이트) 회원가입 -> 19세 이상 ~ 60세 미만
// - 입력하신 나이 25세는 회원가입 성공입니다.
// - 입력하신 나이 12세는 회원가입 실패입니다.
int age = 25; //사용자 입력
//String result1 = age >= 19 && age < 60 ? "성공" : "실패";
String result1 = ((age >= 19) && (age < 60)) ? "성공" : "실패";
System.out.printf("입력하신 나이 %d세는 회원가입 %s입니다.", age, result1);
Author And Source
이 문제에 관하여(학원 5일차 - Java), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@hi-dae-in/국비-학원-5일차저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)