• Home
  • About
    • Young's Github Pages photo

      一日不作一日不食

    • About
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

Java 정리 03

15 Nov 2018

Reading time ~11 minutes

Java 정리 03 - 연산자


연산자 우선순위

  • 최단산쉬관리삼대콤마

01


진수

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);
    }
}

진법변환

02

03

  • 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)
      • 윈도우는 프로그래머용 계산기 지원(우와)

04

05

  • 8진수를 2진수로 변환
    • 숫자 하나당 비트 3개로 대치되고 첨자는 4 2 1 로 사용

06

  • 16진수를 2진수로 변환
    • 숫자 하나당 비트 4개로 대치되고 첨자는 8 4 2 1 로 사용

07


음수의 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) - 상위비트와 하위비트가 모두 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 발생
// 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형으로 변환

08

// 문자열을 정수로 바꾸는 방법
// 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!

숙제풀이1

숙제풀이2

숙제풀이3



Java