Java 정리 03
15 Nov 2018
Reading time ~11 minutes
Java 정리 03 - 연산자
연산자 우선순위
- 최단산쉬관리삼대콤마
진수
10진수 0 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
// 8진수는 숫자 앞에 0 붙여 사용
8진수 0 1 2 3 4 5 6 7 10 11 12 13 ...
// 16진수는 숫자 앞에 0x 붙여사용
16진수 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 ...
2진수 0 1 10 11 100 101 110 111 1000 1001 ...
// 컴퓨터는 연산 시 모두 2진수로 바꿔 처리
class NumberSystem {
public static void main(String[] args) {
int deci = 15; // 10진수
int octal = 017; // 8진수
int hex = 0xF; // 16진수
System.out.println(deci+" / "+octal+" / "+hex);
}
}
진법변환
- 10진수를 2진수로 변환
- 첨자는 배로 뛴다
- 연습문제
- 10 - 0000 1010(2)
- 89 - 0101 1001(2)
- 29 - 0001 1101(2)
- 50 - 0011 0010(2)
- 99 - 0110 00112)
- 300 - 1 0010 1100(2)
- 윈도우는 프로그래머용 계산기 지원(우와)
- 8진수를 2진수로 변환
- 숫자 하나당 비트 3개로 대치되고 첨자는 4 2 1 로 사용
- 16진수를 2진수로 변환
- 숫자 하나당 비트 4개로 대치되고 첨자는 8 4 2 1 로 사용
음수의 2진 표현
- 음수를 2진수로 나타낼 땐 2의 보수법 사용
- 2의보수 = 1의보수 + 1
- -5 -> 절대값처리 -> 5 -> 2진수화 -> 0101 -> 2의보수화 - 1011
- 컴퓨터는 0도 양수로 인식
3 - 0000 0011
2 - 0000 0010
1 - 0000 0001
0 - 0000 0000
-1 - 1111 1111
-2 - 1111 1110
-3 - 1111 1101
-4 - 1111 1100
단항연산자
- 연산에 사용되는 항이 하나인 연산자
// 대상체는 변수거나 상수
연산자 대상체;
~ // tilde 1의 보수연산, 부호,값 바뀜
! // NOT
+ // 형식적 제공
- // 2의 보수연산(부호바꿈연산) 부호만 바뀜
++ // 증가연산
-- // 감소연산
~10 // -11, 부호바뀌고 1증가, 0000 1010 -> 1의보수 -> 1111 0101
~-11 // 10, 부호바뀌고 1감소, 1111 0101 -> 1의보수 -> 0000 1010
// ~양수 : 부호변경 1증가
// ~음수 : 부호변경 1감소
// ! : NOT (true -> false, false -> true)
!true // false
!false // true
!(3>2) // !(true) -> false
+ // 형식적 제공
10
+10
- // 2의 보수연산(부호바꿈연산)
-10 // 값은 그대로 부호바뀜
// tilde(~)를 안쓰는 이유는 번거롭기 때문
/*
단항연산자 (Unary)
~, !, +, -, ++, --
*/
class Operator1 {
public static void main(String[] args) {
int i = 11;
int j = -11;
// ~(tilde) : 1의 보수연산
// ~양수 : 부호변경 1증가
System.out.println("~"+i+" = "+ ~i); // -12
// ~음수 : 부호변경 1감소
System.out.println("~"+j+" "+ ~j); // 10
// !(NOT) : true -> false, false -> true
boolean b = true;
boolean c = false;
System.out.println("!b = "+!b); // false
System.out.println("!c = "+!c); // true
System.out.println(11>15); // false
// !은 boolean에만 사용가능
System.out.println(!(11>15)); // true
// + : 형식적 제공
System.out.println("+"+i+" = "+ +i); // 11
System.out.println("+"+j+" = "+ +j); // -11
// - : 2의 보수연산, 부호바꿈연산(값 그대로)
System.out.println("-"+i+" = "+ -i); // -11
System.out.println("-"+j+" = "+ -j); // 11
}
}
- ++, --
- 대상체의 값을 변경하는 연산자
- 상수에는 사용할 수 없다
- 두가지 형식으로 사용가능
- 전위, 후위 연산
- ++ : 대상체의 값을 1씩 증가
- -- : 대상체의 값을 1씩 감소
- 대입연산자와 함께 사용되거나 method의 Arguments로 전달되는 경우에는 전위와 후위가 다른 값을 할당함
- 전위 : 내 것 먼저 (대상체의 값을 먼저 변경)
- 후위 ; 남의 것 먼저 (대입먼저 한 후 대상체의 값을 변경)
int i = 0;
int j = 10;
// 전위연산 : 연산자 대상체
++i; // 1
--j; // 9
// 후위연산 : 대상체 연산자
i++; // 2
j--; // 8
// 증가연산자와 감소연산자는 대입연산자와 함께 사용되면
// 전위 후위가 다른 값을 대입
// 전위 : 내것 먼저
j = 0;
j = ++i; // i, j 모두 3
// 후위 : 남의 것 먼저
j = 0;
j = i++; // i는 4, j는 3
산술연산자
- +,-,*,/,%
- 대상체 연산자 대상체
- 예제는 생략
쉬프트연산자
- 비트 밀기 연산
<< - left shift
>> - right shift
>>> - unsigned right shift
// 대상체 연산자 밀칸수
// << : 비트를 왼쪽으로 밀고 밀어서 생긴 빈칸을 항상 0으로 채움
5 << 3 // 0000 0101 (5) -> 0010 1000 (40)
// >> : 비트를 오른쪽으로 밀고 밀어서 생긴 빈칸을
// 최상위 부호비트(MSB)에 따라 양수면 0, 음수면 1을 채운다
// >>> : 비트를 오른쪽으로 밀고 밀어서 생긴 빈칸을 0으로만 채운다
10 << 2
// 0000 1010 (10)
// 0010 1000 (40) *2*2
1 << 31
// 0000 ... 0001
// << 31 하면 1000 ... 0000, MSB값이 바뀌므로 가장 작은 값이 나옴
// << 32 하면 다시 제자리로 옴 1
17 >> 2
// 0001 0001
// 0000 0100, 넘어간 값은 버려짐, 4가 됨
// 1 >> 100 => 0 // 0으로 채워지니까
// -1 >> 100 => -1 // 1로 채워지니까
19 >>> 3
// 0001 0011
// 0000 0010
-1 >>> 1
// 1111 ... 1111
// 0111 ... 1111, unsigned로 0이 채워지므로 양수 최대값이 나옴
// java.lang 패키지 Integer클래스엔
// 진법반환하는 static method들이 존재
// method : static method 사용
// 클래스명.method명(값)
int i=11;
System.out.println("i의 이진수값 : "+Integer.toBinaryString(i)); // 1011
System.out.println("i의 8진수값 : "+Integer.toOctalString(i)); // 013
System.out.println("i의 16진수값 : "+Integer.toHexString(i)); // 0xb
/*
쉬프트연산자
<< (left shift)
- 비트를 왼쪽으로 밀고 밀어서 생긴 빈칸을 항상 0으로 채움
>> (right shift)
- 비트를 오른쪽으로 밀고 밀어서 생긴 빈칸을
- MSB에 따라 양수면 0, 음수면 1을 채움
>>> (unsigned shift)
- 비트를 오른쪽으로 밀고 밀어서 생긴 빈칸을 항상 0으로 채움
*/
class Operator3 {
public static void main(String[] args) {
int i = 9;
// 0000 1001
// <<3 0100 1000 = 72
// 쉬프트연산자는 산술연산자보다 우선순위가 낮기 때문에 가로 필요
System.out.println(i+"<<3 = "+ (i<<3));
i = 36;
// 0010 0010
// >>3 0000 0100 = 4
System.out.println(i+">>3 = "+ (i>>3));
i = 120;
// 0111 1000
// >>>4 0000 0111 = 7
System.out.println(i+">>>4 = "+ (i>>>4));
i = 1;
// 0000 ... 0001
// <<31 1000 ... 0000
// MSB가 변경되며 음수의 최대값이 출력됨
System.out.println(i<<31); // -2147483648
// literal이 4byte이므로 32칸 밀면 제자리로 돌아옴
System.out.println(i<<32); // 1
i = -1;
// right shift로 밀어봤자 밀린 공간에
// 1이 차기 때문에 값은 유지됨
System.out.println(i>>100); // -1
i = -1;
// 1111 ... 1111
// 0111 ... 1111
// MSB가 0으로 변경, 양수의 최대값 출력
System.out.println(i>>>1); // 2147483647
}
}
관계연산자
- >, <, >=, <=, ==, !=
/*
관계 연산자
>, <, >=, <=, ==, !=
*/
class Operator4 {
public static void main(String[] args) {
int i=11, j=15, k=11;
System.out.println(i+" == "+k+" = " + (i==k)); // true
System.out.println(i+" == "+j+" = " + (i==j)); // false
System.out.println(i+" != "+k+" = " + (i!=k)); // false
System.out.println(i+" != "+j+" = " + (i!=j)); // true
}
}
논리연산자
- 일반논리 : 여러개의 관계 연산자를 붙여서 연산할 때 사용
- && (AND) - 전항과 후항이 모두 참일 때만 true반환
- 전항이 false면 후항을 계산하지 않음
-
** (OR)** - 전항과 후항 모두 거짓일 때만 false반환 - 전항이 true이면 후항을 계산하지 않음
- && (AND) - 전항과 후항이 모두 참일 때만 true반환
- 비트논리 : 비트를 합치거나 분리할 때 사용
- &(AND) - 상위비트와 하위비트가 모두 1일 때만 1내림
-
** (OR)** - 상위 비트와 하위비트가 모두 0일 때만 0내림 - ^(XOR, Exclusive Or) - 상위 비트와 하위비트 둘 중 하나만 1인경우 1내림
9 & 3 = 1
// 0000 1001
// & 0000 0011
// = 0000 0001
9 | 3 = 11
// 0000 1001
// | 0000 0011
// = 0000 1011
9 ^ 3 = 10
// 0000 1001
// ^ 0000 0011
// = 0000 1010
/*
논리연산자 :
일반논리
&&(AND) : 전항과 후항이 모두 true일 때만 true반환
||(OR ) : 전항과 후항이 모두 false일 때만 false 반환
비트논리
&(AND) : 상위비트와 하위비트가 모두 1일 때만 1내림
|(OR ) : 상위비트와 하위비트가 모두 0일 때만 0내림
^(XOR) : 상위비트와 하위비트 둘 중 하나만 1인 경우 1내림
*/
class Operator5{
public static void main(String[] args){
boolean flag1 = true, flag2 = false, flag3 = true, flag4 = false;
System.out.println("--------&&---------");
// 논리연산은 산술연산보다 우선순위가 낮기 때문에 가로로 묶는다
System.out.println(flag1+"&&"+flag3+" = "+ (flag1&&flag3)); // true
System.out.println(flag1+"&&"+flag2+" = "+ (flag1&&flag2)); // false
System.out.println(flag2+"&&"+flag1+" = "+ (flag2&&flag1)); // false
System.out.println(flag2+"&&"+flag4+" = "+ (flag2&&flag4)); // false
// 전항이 false면 후항은 계산하지 않고 false인 결과를 만든다
System.out.println("--------||---------");
System.out.println(flag1+"||"+flag3+" = "+ (flag1||flag3)); // true
System.out.println(flag1+"||"+flag2+" = "+ (flag1||flag2)); // true
System.out.println(flag2+"||"+flag1+" = "+ (flag2||flag1)); // true
System.out.println(flag2+"||"+flag4+" = "+ (flag2||flag4)); // false
// 전항이 true면 후항은 계산하지 않고 true인 결과를 만든다
System.out.println("-------------------------");
flag1 = false;
flag2 = false;
flag3 = false;
flag3 = (flag1=3>4)&&(flag2=5>4);
// flag1까지만 수행하고 flag2는 수행 안함(false 만나면 빠져나옴)
System.out.println("전항:"+flag1+", 후항:"+flag2+", 판정:"+flag3);
System.out.println("-------------------------");
int i=0, j=0;
i = 28; // 0001 1100
j = 48; // & 0011 0000
// 0001 0000 16
System.out.println(i+" & "+j +" = "+(i&j));
i = 16; // 0001 0000
j = 3; // | 0000 0011
// 0001 0011 19
System.out.println(i+" | "+j +" = "+(i|j));
i = 10; // 0000 1010
j = 12; // ^ 0000 1100
// 0000 0110 6
System.out.println(i+" ^ "+j +" = "+(i^j));
}
}
삼항연산자
조건식 ? 항1 : 항2
// 조건식 - 관계연산자
// 항1, 항2 - 상수, 변수, 연산식 들어올 수 있음
// 조건식이 true면 항1 반환
// 조건식이 false면 항2 반환
// 사용예) i>=0 ? "양수" : "음수"
/*
삼항(조건)연산자
*/
class Operator6 {
public static void main(String[] args) {
int i = 9;
// 연산자 우선순위 때문에 가로로 묶는다
System.out.println(i+"는(은) "+ (i>=0?"양수":"음수"));
// 절대값
System.out.println(i+"의 절대값 "+ (i>=0?i:-i) );
// 변수의 값이 짝수인지 홀수인지 판단하는 삼항연산자를 만드세요
System.out.println(i+"는 "+(i%2==0? "짝수입니다.":"홀수입니다."));
}
}
대입연산자
// 순수대입
=
// 연산한 결과를 변수에 대입
+=, -=, *=, /=, %= // 산술대입
<<=, >>=, >>>= // 쉬프트대입
&=, |=, ^= // 비트논리 대입
int i = 15; // 익숙치 않으면 풀어쓰다가 줄여사용하도록 노력
i += 5; // i = i + 5; -> 20
i -= 3; // i = i - 3; -> 17
i *= 2; // i = i * 2; -> 34
...
i = 20;
i <<= 2; // 80
// 0001 0100
// 0101 0000
i = 20;
i &= 15; // 4
// 0001 0100
// 0000 1111
// 0000 0100 = 4
/*
대입연산자
=,
+=,-=,*=,/=,%=
<<=,>>=,>>>=
&=, |=, ^=
*/
class Operator7{
public static void main(String[] args){
int i = 3; // 대입
// 산술대입
i += 2; // 5
i -= 1; // 4
i *= 3; // 12
i /= 4; // 3 자바에선 정수/정수 = 정수!(실수X)
i %= 2; // 1
// 쉬프트 대입
i <<= 4; // 0000 0001 -> 0001 0000 = 16
i >>= 1; // 0001 0000 -> 0000 1000 = 8
i >>>= 2; // 0000 0100 -> 0000 0010 = 1
// 비트논리 대입
i &= 12; // 0000 0001 & 0000 1100 = 0000 0000 = 0
i |= 11; // 0000 0000 | 0000 1011 = 0000 1011 = 11
i ^= 7; // 0000 1011 ^ 0000 0111 = 0000 1100 = 12
System.out.println(i);
}
}
문자열 비교
- 문자열은 관계연산자 중 ‘==’으로 같다를 비교할 수 있음
- 단, 문자열이 기본형 형식으로 만들어진 경우에만!
- 문자열을 비교할 때에는 equals method 사용
// 기본형 형식 - '==' 비교 됨
String s = "안녕!";
// 참조형 형식 - '==' 비교 안됨
String s = new String("안녕!");
// equals method 사용
// 문자열변수.equals("비교할문자열") 이렇게 사용
Strings s = "안녕!"
s.equals("안녕") // false
s.equals("안녕!") // true
main method에 Arguments 입력
- 메소드의 Parameters에 들어가는 값을 Arguments라고 함
- main method는 Java를 실행할 때 호출
- 실행시 외부에서 java 프로그램 내부로 값을 전달할 수 있다.
- 프로그램이 동적으로 동작
- 입력되는 값의 데이터형은 “문자열(String)”
- main method 내에서는 배열로 처리됨
- 배열은 PL/SQL의 테이블타입 변수와 같다 => index 사용
- 인덱스는 오라클에선 1번부터 시작, 다른 모든 언어는 0번부터 시작
- 입력된 값을 배열의 인덱스로 사용
- 없는 인덱스를 사용하면 error 발생
- 배열은 PL/SQL의 테이블타입 변수와 같다 => index 사용
// Test class의 main method를 호출하여 실행
> java Test
// 값들이 main method의 파라미터로 들어온다
> java Test 값1 값2 값3 값4 ...
// 띄어쓰기로 구분된 값1, 값2, .. 들을 Arguments(인수값) 이라고 함
...
public static void main(String[] args) {
// (String[] args)가 main method의 파라미터
// args[0] = 값1, args[1] = 값2, ...
// 이렇게 String배열에 arguments들이 들어감
// 없는 인덱스를 사용하면 error 발생,
...
/*
Java 프로그램 외부에서 Java 프로그램 내부로 값을
전달할 때 main method의 Arguments 사용
실행) java bytecode명 값1 값2 값3 ...
*/
class MainArguments {
public static void main(String[] args) {
System.out.println(args[0]); // 11
System.out.println(args[1]); // 15
System.out.println(args[0]+args[1]); // 1115, 문자열은 +로 합쳐진다
// 문자열은 +제외한 산술연산이 안됨
// System.out.println(args[0]*args[1]);
}
}
문자열을 정수로 바꾸기
- java.lang 패키지 Integer 클래스의 parseInt static method 사용
- String형을 받아서 int형으로 변환
// 문자열을 정수로 바꾸는 방법
// int i = args[0]; error!
// int i = (int)args[0]; error!
// java.lang 패키지 Integer 클래스의 parseInt클래스를 사용해서
// String 타입을 int형으로 변환
int i = Integer.parseInt(args[0]); // 11
int j = Integer.parseInt(args[1]); // 15
System.out.println(i * j); // 165
// 입력된 문자열이 숫자가 아니면 error!