티스토리 뷰
1. 데이터의 타입
- 정수 : byte(1바이트), char(2바이트), short(2바이트), int(4바이트), long(8바이트)
- 실수 : float(4바이트), double(8바이트)
- 논리 : Boolean(8바이트)
- Double은 float보다 정확성이 높다.
- Char은 문자 1개를 보관하기 위한 타입이다. 단지 문자를 그대로 보관하는 것이 아니라 문자에 할당된 코드를 보관하게 된다.
2. 문자집합(Character Set)
- ASCII = 영어권문자로 밖에 표현하지 못함
- UTF-8 = 다국어 문자표현 가능
- Keystroke(키를 누르는 행위) -> 정수값으로 변환(Keycode)
- (1) Encoding : 문자 -> 키코드(정수)로 변환
- (2) Decoding : 키코드(정수) -> 문자로 변환
3. 타입변환
- 데이터 타입을 다른 타입으로 변환하는 것 ( LValue를 변환시키는 것이다. )
- Ex) byte -> int, int ->double
- (1) 자동(묵시적) 타입변환 : Promotion
- (2) 강제(명시적) 타입변환 : Casting
- (1) 자동 타입변환 : 프로그램 실행 도중 작은 타입은 큰 타입으로 자동 타입 변환
- 큰 크기 타입 = 작은 크기 타입(큰 타입이 오른쪽으로 가야한다.)
- EX) intValue = charValue;
- Ex) byte(1) < short(2) < int(4) < long(8) < float(4) < double(8)
- 정수타입보다는 실수타입이 더 크다.
- +) 피연산자는 연산을 당하는 자로 100 + 200 = 300이라고 할 때 피연산자는 100과 200, 연산자는 +를 의미한다.
- +) 이때 피연산자는 타입이 같아야 연산자가 구동이 된다.
- (2) 강제 타입변환 : 큰 타입을 작은 타입 단위로 쪼개기
- 끝의 한 부분만 작은 타입으로 강제적 변환
- EX) 작은 크기 타입 = (작은 크기 타입) 큰 크기 타입
- Ex) Int를 byte에 담을 때 사용한다.
- EX) int intValue = 103029770;
- byte byteValue = (byte) intValue
- -> 원래값이 보존되지 않는다.
4. 연산이란?
- 데이터를 처리하여 결과를 산출하는 것이다.
- 연산자 : 연산에 사용되는 표시나 기호 ( +, -, *, /, %, =, . . .)
- 피연산자 : 연산대상이 되는 데이터 ( 리터럴, 변수 )
- 표현식(연산식) : 연산자와 피연산자로 이루어진 식이다.
5. 연산의 우선 순위와 방향 ( PPT 4, 6페이지 )
- >, <와 같이 비교 연산자는 왼쪽을 대상(중심)으로 생각한다.
- ‘&&’는 그리고 라는 의미이다.
- %는 나누기의 나머지를 구하는 연산자이다.
- 대부분의 연산자가 왼쪽에서 오른쪽으로 진행되지만, 대입 연산자(=)는 오른쪽에서 왼쪽으로 연산된다.
6. 단항 연산자
- 부호연산자 ( + , - ) : 부호연산자의 산출 타입은 int이다.
7. 증감 연산자 ( ++ , -- )
- 변수의 값을 1증가 시키거나(++) 1감소(--) 시키는 연산자
- 증감 연산자가 변수 뒤에 있으면
01. public class Sample14 { // 각 타입의 리터럴
public static void main(String[] args) {
int intVar = 10;
long longVar = 10L; // 롱 타입의 리터럴은 뒤어 대소문자 L을 붙이게 된다.
float floatVar = 3.14159F; // 플롯트 타입의 리터럴은 뒤에 대소문자 뒤에 F를 붙이게 된다.
// --> 그 이유는 정수나 실수타입의 리터럴은 기본적으로 int나 double로 받아들이기 때문이다.
double doubleVar = 3.14159;
boolean isMale = false;
// char charVar ='A'; // OK!
// 캐릭터 타입은 문자 하나를 보관하는 타입이다. AB처럼 두개의 문자를 보관할 수는 없다.
// char charVar = '1'; // OK!
char charVar = '한'; // OK!
// 문자 그대로 보관하는 것이 아니라 '한'에 해당되는 Keycode 값을 보관하게 된다.
// 실제로 이렇게 하면 charVar의 변수가 반복정으로 선언되고 정의되기 때문에 char1 2 3 이렇게 변환하던지 주석처리해야 한다.
} // main
} // end class
02. public class Sample15 { // byte 타입
public static void main(String[] args) {
byte var1 = -128;
byte var2 = -30;
byte var3 = 0;
byte var4 = 30;
byte var5 = 127;
// byte var6 = 128; // 컴파일러 에러
// byte 타입의 표현범위 : -128 ~ + 127
// 실무에서는 그냥 정수면 int, 실수는 double를 사용하는 것이 편하다.
// 자동으로 타입변환되지 않은 이유는 순수한 리터럴은 타입변환되지 않고 그릇에 집어넣으려고 하는 성질이 있다.
// 리터럴은 자동으로든 강제로든 타입변환이 불가능하다.
System.out.println(var1);
System.out.println(var2);
System.out.println(var3);
System.out.println(var4);
System.out.println(var5);
} // main
} // end class
03. public class Sample16 { //char 타입
public static void main (String[] args) {
char c1 = 'A'; // 문자로 직접 저장
char c2 = 65; // 십진수로 저장 ( 65 = A ) ---> 키코드 값으로 저장되어도 이에 해당되는 문자인 A로 출력된다.
char c3 = '\u0041'; // 16진수로 저장 ( \u0041 = A ) ---> 키코드 값으로 저장되어도 이에 해당되는 문자인 A로 출력된다.
// ===========================
char c4 = '가'; // 문자를 직접 저장
char c5 = 44032; // 십진수로 저장 ( 44032 = 가 ) ---> 키코드 값으로 저장되어도 이에 해당되는 문자인 '가'로 출력된다.
char c6 = '\uac00'; // 16진수로 저장 ( \uac00 = 가 ) ---> 키코드 값으로 저장되어도 이에 해당되는 문자인 '가'로 출력된다.
// ================================
int unicode = c1; // A의 유니코드 얻기 ----> c1이 char로 문자를 얻기위한 타입일지라도 int는 정수타입이기에 c1문자의 키코드값인 65를 정수로 저장하게 된다.
System.out.println(c1); // ----> A
System.out.println(c2); // ----> A
System.out.println(c3); // ----> A
System.out.println(c4); // ----> 가
System.out.println(c5); // ----> 가
System.out.println(c6); // ----> 가
System.out.println(unicode); // ----> 65
// 실무에서는 문자의 변수의 경우 그냥 char로 사용하면 된다.
// ex) char c1 = 'A';
} // main
} // end class
04. public class Sample17 { // 기본적으로 정수는 int! 실수는 double 타입으로 저장된다!
public static void main (String[] args) {
long var1 = 10;
// 10 뒤에 L이 붙여있지 않기에 기본적으로 int 타입으로 저장이 된다.
long var2 = 20L;
// 뒤에 L을 붙여야만 long타입으로 저장이 되기에 주의해야 한다.
// long var3 = 1000000000000; // 컴파일러 오류 // Rvalue에서 오류가 난 것이 아니라 Lvalue에서 이미 오류가 난 상태이다.
long var4 = 1000000000000L;
// L을 붙여야만 long 타입으로 저장이 되고, 그렇지 않으면 int타입으로 저장이 된다.
// ===================================
System.out.println(var1);
System.out.println(var2);
System.out.println(var4);
} // main
} // end class
05. public class Sample18 { // boolean 타입
public static void main (String[] args) {
boolean stop = false;
if (stop) {
System.out.println("중지합니다."); // 참이라면
} else {
System.out.println("시작합니다."); // 거짓이라면
} // if -else
} // main
} // end class
06. public class Sample19 { // Promotion 자동형변환
public static void main(String[] args) {
byte byteValue = 10;
int intValue = byteValue;
// Lvalue와 Rvalue의 타입이 똑같아야 대입이 이루어진다.
// 하지만, 이 경우 byte와 int라는 서로 다른 타입으로 되어있는데 잘 출력되고 있음을 볼 수 있다.
// byte가 자동으로 int타입으로 변환되어 저장이 된 것이다.
// 자동형변환은 작은 타입이 큰 타입으로 변환되는 것을 의미한다.
// 큰 타입에서 작은 타입으로 변환할때에는 강제변환이 필요하다.
System.out.println(intValue);
// ================================================
char charValue = '가';
intValue = charValue;
// int가 4바이트 char가 2바이트이기에, int가 더 크기가 커서 자동형변환이 가능하다.
System.out.println("가의 유니코드 =" + intValue); // -----> 가의 유니코드 =44032로 출력이 된다.
// charValue가 '가'를 저장하였으나 intValue에 넣음으로써 int타입으로 자동형변환되었기에 44032로 출력이 된다.
// 문자열("")의 타입은 String이다. [참조타입이다.]
// 문자를 나타날때에는 '' 문자열을 나타낼때에는 ""를 사용한다.
// 참조타입은 기본타입보다 무조건 크다.
// ===================================================
} // main
} // end class
07. public class Sample20 { // 강제형변환
public static void main (String[] args) {
int intValue = 44032;
char charValue = (char) intValue; // 4바이트인 int타입을 2바이트인 char로 쪼개라
System.out.println(charValue); // 44032의 경우 2바이트로 충분히 나타낼 수 있기에, 이 경우 데이터 손실이 일어나지 않는다.
// 자동형변환은 데이터손실이 없지만, 강제형변환은 데이터손실이 있을수도 없을 수도 있다.
// =====================================
long longValue = 500;
intValue = (int)longValue; // 8바이트의 long 타입을 4바이트의 int 타입으로 쪼개라.
System.out.println(intValue); // 500의 경우 2바이트만으로도 구현가능하기에, 이 경우 데이터 손실이 일어나지 않는다.
// ======================================
double doubleValue = 3.14;
intValue = (int) doubleValue; // Lvalue와 Rvalue의 타입이 다르기에 Rvalue를 Lvalue로 변환시켜 준다. (******)
// double가 실수타입이도 3.14라는 값이 충분히 4바이트 안에 구현이 가능은 하지만, 정수타입인 int타입으로 변환해서 넣었기에 실수부분인 0.14는 버리게 된다.
// 실수타입을 정수타입으로 강제변환하게 되는 경우 정수타입으로 저장이 되기에 소숫점 단위는 자동으로 버리게 된다. (*****)
// 실수 중 소숫점을 버리기 위해 사용되는 기법이다.
// Lvalue(왼쪽)의 형태로 맞춰진다고 생각하면 편하다.
System.out.println(intValue); // -------> 3으로 출력이 된다.
} // main
} // end class
08. public class Sample21 { // 정수 타입의 연산 결과는 기본적으로 int!!!!!!
public static void main (String[] args) {
byte byteValue1 = 10;
byte byteValue2 = 20;
// byte byteValue3 = byteValue1 + byteValue2; // 컴파일러 오류
// byteValue1 + byteValue2는 서로 byte 타입이기에 연산 자체는 30으로 가동되지만,(*****)
// 연산된 결과물인 30이 int 타입으로 되어버리기 때문이다. (****)
// 이를 해결하기 위해서는
// byte byteValue3 = (byte) (byteValue1 + byteValue2); 로 작성해야 한다.
// 정수 타입의 연산 결과물은 기본적으로 int로 가정되어 버린다. (******)
// 결과물이 int의 범위를 넘어가게 될 때에만 long이 되고, 그렇지 않으면 int로 된다.(*****)
int intValue1 = byteValue1 + byteValue2;
System.out.println(intValue1);
} // main
} // end class
09. public class Sample22 { // 자동형변환 응용
public static void main (String[] args) {
double number1 = 10.23;
byte number2 = 20;
// int result = number1 + number2; // 컴파일러 오류 ---> 연산이 가동되기 위해서 정수타입인 byte를 실수타입인 double로 변환하였기에
// 연산결과물이 실수로 나왔고 이는 int와 타입이 같지 않다.
// 4타입인 int타입 보다 8타입인 double이 크기가 더 크기에 자동형변환이 불가능하다.
double result = number1 + number2; //로 수정해야 한다.
// byte number1 = 10;
// byte number2 = 20;
// double result = number1 + number2; -----> 결과물이 30.0으로 나온다.
// number1 + number2이 정수타입이기는 하지만 Lvalue이 실수타입인 double이기에 정수보다 큰 실수타입으로 자동형변환이 되어 버리기에 30.0으로 출력이 된다.
// 이를 30으로 출력하고 싶다면, 정수타입인 int로 쪼개면 되는데 (***)
// System.out.println((int)result);로 수정하면 된다. (***)
System.out.println(result);
} // main
} // end class
10. public class Sample23 { // 강제형변환 응용
public static void main(String[] args) {
int number1 = 100;
int number2 = 3;
// + (덧셈), - (빼기), * (곱셈), / (나눗셈)
double result = (double) number1 / number2;
// 소숫점을 나타내기 위해서는 정수타입인 int를 실수타입으로 변환해야 하기 때문에 double로 강제형변환시켜야 한다.
// 아니면 number1이나 number2를 double로 바꿈으로써 연산식에서 자동형변환을 이끌어내는 방법도 있다. (***)
// 강제형변환은 복잡한 작업이기에 자동형변환을 추구하는 것이 좋다.
// 그렇기에 위의 방법 보다는
// double number1 = 100;
// int number2 = 3;
// double result = number1 / number2; 로 변환하는 것이 좋다.
System.out.println(result); // -----> 3.333333333336으로 출력이 된다.
//sysout을 치고 컨트롤 시프트를 누르면 System.out.println();이 자동완성된다. (*)
} //main
} // end class
11. public class Sample24 { // 연산자
public static void main (String[] args) {
// 1. 부호(sign) 연산자( +, - ) 실습예제
int x = -100;
int result1 = +x;
int result2 = -x;
// + (문자열연결연산자) : concatenation operator
System.out.println("result1=" + result1); // ""안에 문자열은 String으로 정수타입보다 큰 참조타입이기에 result1은 자동으로 참조타입으로 변환된다.
System.out.println("result2=" + result2);
// =======================================
// (중요!) : 부호연산자의 결과타입은 int이다!!!(*****)
short s = 100;
// short result3 = -s; // 컴파일러 에러 <---- -s의 결과가 int타입으로 나오기 때문에 에러가 생기게 된다.
// 자동형변환은 Lvalue가 Rvalue보다 커야지만 가능하다.
int result3 = -s;
System.out.println("result3="+ result3);
} // main
} // end class
12. public class Sample25 { // 증감 연산자
public static void main (String[] args) {
int x = 10;
int y = 10;
int z;
System.out.println("-------------------");
// 증감 연산자가 단독으로만 사용되는 경우에는, 전위/후위의 의미가 없다.
x++; // 후위 증가 연산자
++x; // 전위 증가 연산자
// x= x+1 => x++, ++x
System.out.println("1. x=" + x);
System.out.println("-------------------");
y--; // 후위감소연산자
--y; // 전위감소연산자
// y= y-1 => --y, y--
System.out.println("2. y=" + y);
System.out.println("-------------------");
System.out.println("3. x=" + x);
z = x++; // 후위 증가연산자 사용! (*******)
// 후위 증가연산자의 경우에는 먼저 z에 x자신의 값을 준 다음에, 후에 1 증가시킨다.
System.out.println("4. z="+ z); // <--- Z=12이 출력, 후위증가연산자이기에 ++연산이 진행되기 전의 x값을 받게 된다.
System.out.println("5. x="+ x); // <--- x=13이 출력, ++연산이 모두 끝난 후의 값을 받게 된다.
System.out.println("-------------------");
z = ++x; // 전위 증가연산자 사용! (*******)
// 전위 증가연산자는 x 자신부터 1을 증가시킨 후에, 그 값을 z로 넘겨준다.
System.out.println("6.z="+ z); // <--- z=14가 출력, 전위증가연산자는 x에 1을 더한 값을 z로 넘기기 때문
System.out.println("7.x="+ x); // <--- x=14가 출력, x에 +1된 값을 받는다.
System.out.println("-------------------"); //(******)
z = ++x + y++;
System.out.println("8. z="+ z); // z=23가 출력, ++x + y++ 중에서 y++는 후위이기에 z = (x= 14+1) + (y=8)로 계산이 된다.
// y의 값은 z의 값이 전부 구해진 후에 +1이 된다.
System.out.println("9. x="+ x); // x= 15가 출력, x에 +1한 값을 받는다.
System.out.println("10. y="+ y); // y=9가 출력, y에 +1한 값을 받는다.
// 최대한 직관적이고 가독성이 높은 코드를 만드는 것이 좋다.
// -----> z = ++x + y++; 가 아니라
// x = x+1;
// z = x+y;
// y = y+1;
// 으로 구성하는 편이 좋다.
} // main
} // end class
13. public class Sample26 { // 부정연산자 NOT(!)
public static void main(String[] args) {
// 부정연산자 NOT(!)의 사용예 -----> 토글(toggle)
// Toggle is like a switch.
boolean play = true;
System.out.println("1." + play);
play = !play; // !는 play의 값을 부정하라 라는 뜻이다. true의 부정인 false를 출력한다.
System.out.println("2." + play);
play = !play; // !는 play의 값을 부정하라 라는 뜻이다. false의 부정인 true를 출력한다.
System.out.println("3." + play);
} // main
} // end class
14. public class Sample27 { // %(나머지) 연산자
public static void main (String[] args) {
int v1 = 5;
int v2 = 2;
// 나눗셈의 결과 = 몫 + 나머지, 이때 %(나머지) 연산자는
// 나눗셈의 결과 중 "나머지"를 반환해준다.
int result1 = v1 % v2;
System.out.println("result1="+ result1); // -------> 1이 출력된다.
} // main
} // end class
15. public class Sample28 { // '%' (나머지) 연산자 응용
public static void main(String[] args) {
// '%' (나머지) 연산자
int number = 8;
// 이때, 8이 2의 배수(짝수)인지 아닌지 판단하는 로직을 어떻게 구현할 것인가.
int result = number % 2;
if (result == 1){System.out.println("홀수입니다!");}else {System.out.println("짝수입니다!");} // if-else구문1
// System.out.println(result);
int result2 = number % 3;
if (result2 == 0){System.out.println("3의 배수입니다!");}else {System.out.println("3의 배수가 아닙니다!");} // if-else구문2
} // main
} // end class
16. public class Sample29 { // 문자타입(char) 응용
public static void main(String[] args) {
// 문자타입(char)을 이용해서, 연산수행 예제
char c1 = 'A' + 1;
// 1. 대전제 1 - 정수연산식은 결과는 int타입이다.
// 2. 대전제 2 - 리터럴은 형변환을 하지 않는다.
// 'A'는 리터럴, 즉 상수 이기에 A의 키코드인 65에 +1을 한 66으로 바뀌어 B가 된다.
char c2 = 'A';
// char c3 = c2 + 1; // 컴파일 에러
// c2가 여기에서는 상수가 아니라 변수로 받아들여지기에 int로 자동형변환된다.
// <------- char은 2바이트이기에 4바이트인 int 변수를 받아들일 수 없기 때문에 에러가 뜬다.
int c3 = c2 + 1;
System.out.println("c1 : " + c1); // ----> c1 : B가 출력
System.out.println("c2 : " + c2); // ----> c2 : A가 출력
System.out.println("c3 : " + (char) c3); // ------> c3 : B로 출력이 된다.
// 위는 int타입의 c3를 char로 강제형변환한 것이다.
} // main
} // end class
'KH 정보교육원 [ Java ]' 카테고리의 다른 글
KH 07일차 - 참조타입 (0) | 2022.03.04 |
---|---|
KH 06일차 - 조건문과 반복문 (0) | 2022.03.03 |
KH 05일차 - 연산자 및 조건문과 반복문 (0) | 2022.03.02 |
KH 03일차 - 변수 (0) | 2022.02.25 |
KH 01 - 02 일차 (0) | 2022.02.24 |