웹개발 수업/JAVA

[Day +3] 선언과 초기화, 형변환, 데이터 오버플로우, printf, escape문자

Chole Woo 2021. 7. 11. 20:12
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()