Java 입문 | 자바 기본 구조 | 연산자(Operator)

대입 연산자

대입 연산자는 프로그래밍을 처음하는 사람이라면 조금 헤깔릴 수 있다. 일반 수학에서의 단일 등호 기호 = 는 같다는 표현으로만 사용되지만, 프로그래밍에서는 변수에 할당 즉, 대입을 의미한다.

아래 예제를 보면 값이나 표현식을 변수에 대입을 한다.

  • 변수 = 값
int a = 1; // 변수 a에 1이 대입된다.
  • 변수 = 표현식
int a = 1 + 2; // 변수 a에 1+2를 하여 3이 대입된다.
  • 변수 = 변수 = 변수… = 값(혹은 표현식)
int a, b, c;
a = b = c = 100 // a, b, c 변수에 동일하게 100이 대입된다.

변수의 표현식의 데이터 타입과 같거나 호환될 수 있어야 한다.

int a = 1;
boolean b = true;
int c = a + b;  // 컴파일 error

산술 연산자

산술 연산자(arithmetic operators)는 일반 수학에 사용되는 것과 같은 방식으로 산술식에서 사용한다.

기본적인 산술 연산자

뎃셈, 뺄셈, 곱셈 나눗셈과 같이 모든 숫자형에 대한 산술 연산을 할 수 있다.

연산자 기능 사용법 사용 설명
+ 덧셈 op1 + op2 op1과 op2를 더한다.
- 뺄셈 (또는 단항 마이너스) op1 - op2 op1과 op2를 뺀다.
* 곱셈 op1 * op2 op1과 op2를 곱한다
/ 나눗셈 op1 / op2 op1을 op2로 나눈다.
% 나머지 op1 % op2 op1을 op2로 나눈 나머지를 구한다.

예제 1)

package com.devkuma.tutorial.operators;

public class Arithmetic {

    public static void main(String[] args) {
        int a = 1 + 3;
        int b = a - 2;
        int c = b * 5;
        int d = c / 2;
        int e = d % 3;

        System.out.println("a=" + a);
        System.out.println("b=" + b);
        System.out.println("c=" + c);
        System.out.println("d=" + d);
        System.out.println("e=" + e);
    }
}

실행 결과:

a=4
b=2
c=10
d=5
e=2

증가 연산자와 감소 연산자

증가 연산자는 하나를 증가시키며, 감소 연산자는 하나를 감소시킨다.

연산자가 어디에 위치에 있나에 따라 다른 결과를 가져오게 된다. 예를 들면 op가 초기 값이 2라고 가정하면 ++op 처럼 연산자를 앞에 오게 되면 증가를 시킨 후인 값 3를 반환하게 되고, op++처럼 연산자가 뒤에 오게 되면 증가 시키기 전 값인 2를 반환하고, op값은 3이 된다.

연산자 기능 사용법 사용 설명
++ 전위(prefix) 증가 ++op op에 값 1 증가, op값이 증가시킨 다음 값을 반환한다.
후위(postfix) 증가 op++ op에 값 1 증가, op값이 증가시키기 전 값을 반환한다.
전위(prefix) 감소 –op op에 값 1 감소, op값이 감소시킨 다음 값을 반환한다.
후위(postfix) 감소 op– op에 값 1 감소, op값이 감소시키기 전 값을 반환한다.

예제 2)

package com.devkuma.tutorial.operators;

public class Increase {

    public static void main(String[] args) {

        int a = 10;

        System.out.println(a++);
        System.out.println(++a);
        System.out.println(a--);
        System.out.println(--a);
    }
}

실행 결과:

10
12
12
10

산술적인 대입 연산자

대입 연산자와 다른 산술 연산자들과 결합하여 쓰이는 형태의 연산자이다. 예를 들면 a += 2이라고 하면 a에 2를 더하고 a에 2를 더한 값을 대입한다.

연산자 기능 사용법 의미
+= 덧셈 대입 op1 += op2 op1 = op1 + op2
-= 뺄셈 대입 op1 -= op2 op1 = op1 - op2
*= 곱셈 대입 op1 *= op2 op1 = op1 * op2
/= 나눗셈 대입 op1 /= op2 op1 = op1 / op2
%= 나머지 대입 op1 %= op2 op1 = op1 % op2

예제 3)

package com.devkuma.tutorial.operators;

public class AssignmentOperator {

    public static void main(String[] args) {
        int a = 4;
        int b = 5;
        int c = 6;

        a += 4;
        b -= 2;
        c += a * b;
        c %= 7;

        System.out.println("a=" + a);
        System.out.println("b=" + b);
        System.out.println("c=" + c);
    }
}

실행 결과는 아래와 같다.

a=8
b=3
c=2

비트 연산자

기본적인 비트 연산자

비트 연산자는 이진 비트연산을 한다.

3과 6을 &(AND) 연산을 하게 되면 0010(3) 과 0110(6)에 대해 각 비트를 AND 를 적용하여 0010 인 결과값 2가 된다.

  • 0011(3) & 0110(6) = 0010(2)
연산자 기능 사용법 사용 설명
& AND op1 & op2 비트 단위의 논리곱
I OR op1 I op2 비트 단위의 논리합
^ XOR op1 ^ op2 비트 단위의 배타적 논리합
~ NOT op1 & op2 비트 단위의 부정

예제 4)

package com.devkuma.tutorial.operators;

public class Bit {

    public static void main(String[] args) {
        int a = 3;
        int b = 6;
        int c = a & b;
        int d = a | b;
        int e = a ^ b;
        int f = (~a & b) | (a & ~b);

        System.out.println("c=" + c);
        System.out.println("d=" + d);
        System.out.println("e=" + e);
        System.out.println("f=" + f);
    }
}

실행 결과:

c=2
d=7
e=5
f=5

시프트 연산자

  • 쉬프트 연산자(shift operators)는 왼쪽 쉬프트(left shift), 오른쪽 쉬프트(left shift), 부호없는 오른쪽 쉬프트(Unsigned Right Shift)가 있다.
  • 부호없는 오른쪽 쉬프트(Unsigned Right Shift) 연산자는 32bit와 64bit에서만 값에서만 사용된다.
연산자 기능 사용법 사용 설명
» NOT op1 » op2 op1을 op2만큼 오른쪽으로 쉬프트
« NOT op1 » op2 op1을 op2만큼 왼쪽으로 쉬프트
»> NOT op1 »> op2 op1을 op2만큼 오른쪽으로 쉬프트하면서 왼쪽에는 항상 부호에 무관하게 0이 채워짐

예제 5)

package com.devkuma.tutorial.operators;

public class Shift {

    public static void main(String[] args) {
        // 1000(8)를 2만큼 오른쪽으로 비트를 옮기면 100000(32)가 된다.
        byte a = 8 << 2;

        // 1000(8)를 2만큼 왼쪽으로 비트를 옮기면 10(2)가 된다.
        byte b = 8 >> 2;

        // -1를 32bit로 표현하면 11111111111111111111111111111111이 되고,
        // 이를 2만큼 오른쪽으로 쉬프트하면서 왼쪽에는 항상 부호에 무관하게 0이 채워짐
        // 그래서 값은 01111111111111111111111111111111(2147483647)이 된다.
        int c = -1 >>> 1;

        System.out.println("a=" + a);
        System.out.println("b=" + b);
        System.out.println("c=" + c);
    }
}

실행 결과:

a=32
b=2
c=2147483647

비트 대입연산자

대입 연산자와 다른 비트 연산자들과 결합하여 쓰이는 형태의 연산자이다.

연산자 기능 사용법 의미
&= AND 대입 op1 &= op2 op1 = op1 & op2
I= OR 대입 op1 I= op2 op1 = op1 I op2
^= XOR대입 op1 ^= op2 op1 = op1 ^ op2
>>= » 대입 op1 »= op2 op1 = op1 « op2
<<= « 대입 op1 «= op2 op1 = op1 « op2
>>>= »> 대입 op1 »>= op2 op1 = op1 »> op2

비트 연산자의 논리 결과표

A B A&B AIB A^B ~A
0 0 0 0 0 1
1 0 0 1 1 0
0 1 0 1 1 1
1 1 1 1 0 0

관계 연산자

관계 연산자는 이항 연산자로서 한 연산항이 다른 연산항에 대해 가지는 관계를 결정한다.

이 연산들의 결과 값은 항상 부울형(true 또는 false)의 형태이기 때문에 if문과 같은 제어문이나 for문 같은 반복문장에 자주 사용된다.

연산자 기능 사용법 사용 설명
> 보다 크다 op1 > op2 op1이 op2보다 큰 경우 true, 아니면 false
>= 보다 크거나 작다 op1 >= op2 op1이 op2보다 크거나 같은 경우 true, 아니면 false
< 보다 작다 op1 < op2 op1이 op2보다 작은 경우 true, 아니면 false
<= 보다 작거나 같다 op1 && op2 op1이 op2보다 작거나 같은 경우 true, 아니면 false
== 같다 op1 II op2 op1과 op2가 같은 경우 true, 아니면 false
!= 같지 않다 !op op1과 op2가 같지 않은 경우 true, 아니면 false
instanceof 인스턴스가 같다 op1 instanceof op2 op1이 op2의 인스턴스(객체)인 경우 true, 아니면 false

예제 6)

package com.devkuma.tutorial.operators;

public class Relation {

    public static void main(String[] args) {

        int a = 10;
        int b = 20;
        int c = 10;

        boolean d = a > b;
        boolean e = a >= b;
        boolean f = a < b;
        boolean g = a <= c;
        boolean h = a == c;
        boolean i = a != b;

        System.out.println("d=" + d);
        System.out.println("e=" + e);
        System.out.println("f=" + f);
        System.out.println("g=" + g);
        System.out.println("h=" + h);
        System.out.println("i=" + i);
    }
}

실행 결과

d=false
e=false
f=true
g=true
h=true
i=true

논리 연산자

논리 연산자는 피연산자(operand)의 값을 평가하여 결과로 true 또는 false값을 반환한다.

특이 사항으로 &&(논리곱)와 ||(논리합) 단축 논리 연산자(Short-circuit logical operator)가 있다. 부하가 1개인 &와 |과는 다르게 하나의 첫 번째 피연산자를 평가한 결과 두 번째 피연산자를 평가할 필요가 없을 경우 바로 결과를 반환하는 연산자이다. 그러기 때문에 두 번째 피연산자에 뭔가 처리가 있는 로직인데 평가를 하지 않게 되면 처리가 되지 않는다.

예를 들면, 아래와 같은 수식에서 flag가 true이면 “count > index++“의 수식은 처리가 되지 않아 index는 증가하지 않는다. 반대로 flag가 false이면 index가 1만큼 증가를 한다.

(flag == true) || (count > index++)
연산자 기능 사용법 사용 설명
& 논리적 AND op1 & op2 op1과 op2가 모두 true인 경우 true, op1과 op2를 모두 평가한다.
I 논리적 OR op1 I op2 op1과 op2중 둘 중 하나 이상이 true인 경우 true, op1과 op2를 모두 평가한다.
^ 논리적 XOR(배타적 OR) op1 ^ op2 op1과 op2중 둘 중 하나 이상이 true인 경우 false, op1과 op2를 모두 평가한다.
&& 짧은 순환 AND op1 && op2 op1과 op2가 모두 true인 경우 true, op1가 false이면 op2를 평가하지 않는다.
II 짧은 순환 OR op1 II op2 op1과 op2중 둘 중 하나 이상이 true인 경우 true, op1가 true이면 op2를 평가하지 않는다.
! 논리적 단항 NOT !op op가 true이면 false, false이면 true

예제 7)

package com.devkuma.tutorial.operators;

public class Logic {

    public static void main(String[] args) {

        boolean a = true;
        boolean b = false;
        boolean c = true;

        boolean d = a & b;
        boolean e = a | b;
        boolean f = a ^ b;
        boolean g = a && b;
        boolean h = a && c;
        boolean i = a || b;
        boolean j = a || c;
        boolean k = !a;

        System.out.println("d=" + d);
        System.out.println("e=" + e);
        System.out.println("f=" + f);
        System.out.println("g=" + g);
        System.out.println("h=" + h);
        System.out.println("i=" + i);
        System.out.println("j=" + j);
        System.out.println("k=" + k);
    }
}

실행 결과:

d=false
e=true
f=true
g=false
h=true
i=true
j=true
k=false

논리 연산자의 논리 결과표

A B A&B AIB A^B ~A
false false false false false true
true false false true true false
false true false true true true
true true true true false false

논리 대입 연산자

대입 연산자와 다른 논리 연산자들과 결합하여 쓰이는 형태의 연산자이다.

연산자 기능 사용법 의미
&= 논리적 AND 대입 op1 &= op2 op1 = op1 & op2
I= 논리적 OR 대입 op1 I= op2 op1 = op1 I op2
^= 논리적 XOR대입 op1 ^= op2 op1 = op1 ^ op2

삼항 연산자

3개의 피연산자 (operand) 가진 3항 연산자 “:?“는 선택문의 if-when-else 문을 축약해서 사용할 수 있다.

  • 조건 ? 수식1(조건이 true인 경우) : 수식2 (조건이 false인 경우)

조건을 평가하여 true인지 false인지 판별하여 true이면 수식1을 false이면 수식2를 실행하여 결과가 반환된다. 조건문(if) 대신에 대입 연산자와 함께 유용하게 사용된다.

예제 3)

public class Three {

    public static void main(String[] args) {
        int a = 2;
        int b = 3;
        int max = (a > b) ? a : b;

        System.out.println("max=" + max);
    }
}

실행 결과:

max=3

연산자 우선순위

우선순위에 상관 없이 수식의 일부분을 괄호 ()로 묶어서 우선순위를 지정할 수 있다.

우선순위 연산자
1 (), [], .
2 ++, --, ~, !
3 *, /, %
4 +, -
5 >>, >>>, <<
6 >, >= , <, <=
7 ==, !=
8 &
9 ^
10 I
11 &&
12 II
13 ?:
14 =, op=

참조