[Day +3] 선언과 초기화, 형변환, 데이터 오버플로우, printf, escape문자
210625 금
Chapter2.
1. 상수 초기화 방법
1) 선언과 동시에 초기화 int age; age = 100;
2) 선언 후 초기화 int age = 100;
*초기화 이후에는 다른 데이터 값을 대입할 수 없다.
<초기화 예시>
입력
package com.kh.variable;
public class C_Constant {
public void finalConstant() {
int age = 20;
final int AGE = 20;
System.out.println("age : " + age);
System.out.println("AGE : " + AGE);
age = 30;
//AGE = 30; => 이미 위에서 20으로 고정했기 때문에 재선언은 불가능하다
System.out.println("age : " + age);
System.out.println("AGE : " + AGE);
}
}
*final
: 최종적이란 뜻을 가지고 있습니다. final 필드는 초기값이 저장되면 최종적인 값이 되어 프로그램 실행 도중에 수정을 할 수 없습니다.
2. 형변환 casting
: 값의 자료형을 바꾸는 것(boolean은 제외)
*원칙은 같은 타입의 자료형들끼리만 계산을 할 수 있다.
1) 자동 형변환
: 컴파일러가 자동으로 값이 작은 자료형을 값이 큰 자료형으로 변환(너무 당연한 것이라 문제가 없음)
예) int a = 12 + double d = 3.3 double result = a + d(자동 형변환)
-long 타입이 float타입으로 변환될 수 있다. why? 모든 실수는 모든 정수보다 표현 범위가 넓기 때문에 (실수 > 정수)
-char타입과 short타입은 서로 형변환이 불가능하다
why? 둘다 할당된 메모리 상의 크기는 2byte로 같으나 short는 32768~32767이고, char 타입은 0~65535이기 때문에 char가 short에 포함 될 수 없다.
-byte와 short값은 서로 연산하면 결국 int값으로 나온다. (예외)
2) 강제 형변환
: 값의 범위가 큰 자료형을 값의 범위가 작은 자료 형으로 변환. 이 때 데이터 손실이 발생할 수 있음. 데이터의 변형, 손실을 감수하고 강제 변환하는 것.
double temp;
int name = (int)temp;
<자동 형변환, 강제 형변환>
package com.kh.variable;
public class D_Cast {
public void rule1() {
boolean flag = true;
//이 친구는 형변환이 불가능하다. 오직 true, false 값만 가질 수 있음
//1. 자동 형변환
//1) 실수와 정수
//(1) int(4byte) => double(8byte)
int i = 12;
double d = 3.3;
double result = i + d;
/* if 강제 형변환을 한다면,
식) double result = (double)i+d; */
//(2) int(4byte) => long(8byte)
int i2 = 22413131;
long l = 100000000L;
long result2 = i2 + l;
/* if 강제 형변환 한다면,
식) long result2 = (long)i2 + l; */
//(3) long(8byte) => float(4byte)
/*Q. 크기는 long이 더 큰데 float로 자동 형변환이 가능한 이유는?
A. 실수인 float가 정수인 long보다 표현 가능한 수의 범위가 더 커서 자동 형변환 가능 */
long l2 = 10000000L;
float f2 = l2;
//2) 실수와 실수
//(1) float(4byte) -> double(8byte)
float f3 = 1.0f;
double d3 = f3;
//3) 문자와 실수
//char(2byte) => int(4byte)
int num = 'A';
System.out.println("num : " + num);
/* int형 변수에 char 리터럴 대입
=> 문자에 해당하는 유니코드 값이 저장됨 */
//4) byte, short를 이용한 연산
byte b2 = 1;
byte b3 = 10;
//byte result3 = b2 + b3;(X)
int result3 = b2 + b3;
/* byte나 short는 서로 혹은 각자 연산 시 무조건 int형으로 처리해줘야 한다. */
}
public void rule2() {
//2. 강제 형변환
//1) 정수와 실수
int iNum = 10;
double dNum = 5.89;
//int iSum = iNum + dNum(X)
//=> 연산 결과가 double이기 때문에 int형 변수를 iSum에 대입 불가
//방법1) 수행 결과를 int형으로 강제 형변환
int iSum = (int)(iNum + dNum);
System.out.println("iSum : " + iSum);
//방법2) Double형 값을 int형으로 강제 형변환
int iSum2 = iNum + (int)dNum;
System.out.println("iSum2 : " + iSum2);
//2) byte, short 연산
byte bNum = 1;
short sNum = 2;
byte bSum = (byte) (bNum + sNum);
short sSum = (short) (bNum + sNum);
System.out.println("bSum : " + bSum);
System.out.println("sSum : " + sSum);
}
public void dataLoss(){
//3. 데이터 손실 테스트
int iNum = 290;
System.out.println("iNum : " + iNum);
//강제 형변환
byte bNum = (byte)iNum;
System.out.println("bNum : " + bNum);
// *예상하기 어려운 데이터 손실이 발생하기 때문에 강제 형변환 시 주의가 필요함
}
}
3. 데이터 오버플로우
예) byte형은 8비트(1byte)인데 -128~127까지가 그것의 범위값이다. byte에 1을 더해주면 결국 128이 되어 범위를 초과하게 된다. 이를 오버플로우라고 한다.
package com.kh.variable;
public class E_Overflow {
public void overflow() {
byte bNum = 127; //127은 byte의 최대값
System.out.println("bNum : " + bNum);
bNum = (byte)(bNum + 1);
System.out.println("bNum : " + bNum);
}
public void calc() {
int num1 = 1000000;
int num2 = 700000;
int multi = num1 * num2;
System.out.println("계산결과 : " + multi);
//int값의 범위를 넘어가서 오버플로우 현상 땜에 음수 값 출력됨.
따라서 int보다 범위 값이 더 큰 long 타입으로 결과 값을 변경해야 함
long multi2 = (long)(num1) * num2;
System.out.println("계산결과 : " + multi2);
//num1 * num2가 연산되는 과정에서 이미 int값으로 인식해서 int값으로 연산이 완료된다.
그러므로 적어도 숫자 중 하나에 대해 long으로 강제 형변환을 해주면 연산이 완료된다.
}
}
4. system.out.printf()
: () 안의 값을 모니터네 출력해주는 메소드 즉, 포맷을 맞춘다(format)
<주로 많이 쓰는 형식>
%d : 정수형
%c : 문자
%s : 문자열
%f :실수
예) %5d : 5칸을 확보하고 오른쪽 정렬을 하겠다
%-5d: 5칸을 확보하고 왼쪽 정렬을 하겠다
package com.kh.variable;
public class F_Printf {
public void printFMethod() {
System.out.println('a');
System.out.printf("%c\n",'a');
//1. printf 사용법
//if 개행하고 싶다면, 역슬래시를 사용한다.
//new line : \n
//tab : \t
/* if 원래 역슬래시를 출력하고 싶을 때는
\\ 역슬래스 두번 입력 */
System.out.printf("%c %c\n", 'a','b');
System.out.printf("%-3c%5c", 'a', 'b');
System.out.println();
System.out.printf("%5d%-5d%5d\n", 100,200,300);
System.out.printf("%s\t%f\t%10.2f\n", "ABC",10.95,10.975);
//10.2 = 10까지는 자리를 잡고 소수 둘째자리에서 반올림하자
//2. 진수
//10진수 100을 10진수, 8진수, 16진수로 나타내면?
System.out.printf("100을 10진 : %5d 8진 : %5o 16진 : %5x\n", 100, 100, 100);
//d, o, x 진수의 값 예)10진수, 8진수, 16진수
//Q. 10진수 100, 16진수 100, 8진수 100을 10진수로 나타내면?
System.out.println("10진수 100 : " + 100);
System.out.println(0x100); // 0x : 16진수라는 의미
System.out.println(0100); // 0*** 8진수라는 의미
}
}
5. escape 문자
<Scanner>
package com.kh.variable;
import java.util.Scanner;
public class B_KeyboardInput {
public void inputScanner2() {
Scanner sc = new Scanner(System.in);
System.out.print("이름 : ");
String name = sc.nextLine();
System.out.print("나이 : ");
int age = sc.nextInt();
sc.nextLine();
/*nextLine을 제외한 다른 메소드는 엔터 값을 읽지 않음.
nextInt가 남겨놓은 엔터 값을 이어서 동작하는 nextLine이 읽고 넘어가는 것이 문제의 원인*/
System.out.print("주소 : ");
String adress = sc.nextLine();
System.out.print("키 : ");
double height = sc.nextDouble();
System.out.println(name + "님은" + age + "세 이며,
사는 곳은" + adress + "이고, 키는 "
+ height + "cm 입니다.");
}
public void inputScanner3() {
Scanner sc = new Scanner(System.in);
System.out.print("이름 : ");
String name = sc.next();
System.out.print("성별(M/F) : ");
char gender = sc.next().charAt(0);
System.out.println(name + "님의 성별은 " + gender + "입니다.");
}
}
next()
문자 또는 문자열을 공백을기준으로 한단어 또는 한문자씩 입력 받는다.
nextLine()
문자 또는 문장 한라인 전체를 입력받는다.
실행
package com.kh.run;
import com.kh.variable.A_variable;
import com.kh.variable.B_KeyboardInput;
import com.kh.variable.C_Constant;
import com.kh.variable.D_Cast;
import com.kh.variable.E_Overflow;
import com.kh.variable.F_Printf;
public class Run {
public static void main(String[] args) {
A_variable var = new A_variable();
//var.declareVariable();
var.initVariable();
B_KeyboardInput kbi = new B_KeyboardInput();
//kbi.inputScanner3();
C_Constant con = new C_Constant();
con.finalConstant();
D_Cast cast = new D_Cast();
cast.dataLoss();
E_Overflow over = new E_Overflow();
//over.overflow();
over.calc();
F_Printf pr = new F_Printf();
pr.printFMethod();
}
}
<명령어 정리>
crtl + shift + O : 임포트 버튼 import
ctrl + space bar : 자동완성
syso : System.out.println()