프로그래밍 언어/Java

[Java] 자바 연산자(Java Operator)

happy_life 2022. 6. 20. 17:25

목차

1. 연산자 정의

2. 연산자 종류

 

 

 

1. 연산자 정의

  • 프로그램에서 데이터를 처리하고 결과를 산출하는 것을 연산(operation)이라고 한다.
  • 연산을 수행하는 기호를 연산자(operator)라고 한다.
  • 연산의 대상을 피연산자(operand)라고 한다.

 

 

2. 연산자 종류

 

종류 연산자 설명
산술 연산자 +, -, *, /, %, <<, >> 사칙연산과 나머지 연산
증감 연산자 ++, -- 피연산자에 저장된 값을 변경한다.
비교 연산자 >, <, >=, <=, ==, != 크고 작고를 비교
논리 연산자 &&, ||, ! 그리고(AND)와 또는(OR) 등으로 조건을 연결
비트연산자 &, |, ^, ~ 비트 단위로 논리 연산을 한다.
대입 연산자 = 우변의 값을 좌변에 저장
기타 (type) ?: instanceof 형변환 연산자, 삼항 연산자, instanceof연산자

 

2-1. 산술 연산자

사칙연산은 기존의 수학과 동일하나, 주의할 점들이 몇가지 있으니 그것을 알아보자.

 

*  나누기 주의할 점: /

  • 피연산자가 정수인 경우, 0으로 나눌 수 없다.
  • 피연산자가 모두 int형인 경우 / 연산자를 사용하면 소수점은 버려진다.

 

 

* 범위를 초과하는 경우 주의할 점:

예시 코드

public class OperatorEx3 {
    public static void main(String[] args) {
        int a = 1000000; // 100만
        int b = 1000000; // 100만
        long c = a * b;
        System.out.println("c = " + c); // 출력결과는? c = -727379968
   }
}

a * b 는 int형의 최대 출력 범위를 넘어선다. 따라서  음수가 출력되게 된다.

이 문제를 해결하기 위해선 a,b 변수를 long 타입으로 형변환 해주어야 한다.

public class OperatorEx3 {
    public static void main(String[] args) {
        int a = 1000000; // 100만
        int b = 1000000; // 100만

        long d = (long)a * b;
        System.out.println("d = " + d); //출력결과는? 1000000000000
    }
}

 

 

* 형이 다를 경우 주의할 점:

1. 작은 것에서 큰것으로는 자동 형변환이 되지만, 반대의 경우는 수동 형변환을 해주어야 한다.

예시코드

public class OperatorEx4 {
    public static void main(String[] args) {
        char c1 = 'A';
        char c3 = (char) (c1 + 1); // 덧셈 결과가 int형이므로 자동 형변환 불가
        System.out.println("c3 = " + c3); //c3 = B

        char c2 = '0'; 
        int a = c1 + c2; // 덧셈 결과가 char형이므로 자동 형변환
        System.out.println("a = " + a); //a = 113
    }
}

*  자동 형변환

byte -> short -> int -> long -> float -> double 

char -> int

 

* 나머지연산자 주의할 점: %

1. 나머지 연산 시 부호는 무시된다. 연산 이 후 나머지 연산을 한 결과에 왼쪽 피연산자의 부호를 붙인 값이 출력 된다.

public class OperatorEx5 {
    public static void main(String[] args) {
        System.out.println(10%8); // 2
        System.out.println(10%-8); // 2
        System.out.println(-10%8); // -2
        System.out.println(-10%-8); // -2
    }
}

 

 

 

2-2. 증감 연산자

피연산자에 저장된 값을 1 증가 또는 감소 시킨다.

연산자가 피연산자의 왼쪽에 위치하는 전위형, 오른쪽에 위치하는 후위형이 있다.

타입 설명 예시
전위형 값이 참조되기 증가시킨다. j = ++i;
후위형 값이 참조된 증가시킨다. j = i++;

 

 

메서드 호출에 포함된 경우 전위형일 때와 후위형일 때의 결과가 다르지만, 독립적으로 하나의 문장으로 쓰이는 경우는 차이가 없다.

 

1) 차이가 있는 예시 코드

public class OperatorEx2 {
    public static void main(String[] args) {

        // 후위형
        int i = 5;
        int j = 0;

        j = i++;
        System.out.println("j=i++; 실행 후, i=" + i +", j="+ j);
	//j=i++; 실행 후, i=6, j=5

        // 전위형
        i = 5;
        j = 0;
        j = ++i;
        System.out.println("j=++i; 실행 후, i=" + i +", j="+ j);
        // j=++i; 실행 후, i=6, j=6
    }
}

 

후위형에서는 아래와 같이 코드가 동작한다.

1. i의 값을 참조하여 j에 5를 저장한다.

2. i를 1 증가시킨다.

 

전위형에서는 아래와 같이 코드가 동작한다.

1. i를 1 증가시킨다.

2. i의 값을 참조하여 j에 6(5+1)을 저장한다.

 

 

2) 차이가 없는 예시 코드

public class OperatorEx1 {
    public static void main(String[] args) {
        // 후위형
        int i = 4;
        i++;
        System.out.println("i = " + i); // i = 5

	// 전위형
        int j = 4;
        ++j;
        System.out.println("j = " + j); // j = 5
    }
}

 

 

 

2-3. 비교 연산자

두 피연산자를 비교하는 데 사용되는 연산으로, 연산결과는 오직 true와 false 중 하나이다.

비교연산자 연산결과
> 좌변 값이 크면, true 아니면 false
< 좌변 값이 작으면, true 아니면 false
>= 좌변 값이 크거나 같으면, true 아니면 false
<= 좌변 값이 작거나 크면, true 아니면 false
== 두 값이 같으면, true 아니면 false
!= 두 값이 다르면, true 아니면 false

 

* 주의할 점: 실수형 비교

예제 코드

public class OperatorEx6 {
    public static void main(String[] args) {
        float f = 0.1f; //0.1은 이진수로 저장할 때 오차가 발생한다.
        double d = 0.1;
        double d2 = (double) f;
        System.out.printf("d==f %b\n", d==f); // d==f false
        System.out.printf("d==d2 %b\n", d==d2); // d==d2 false
        System.out.printf("f==d2 %b\n", f==d2); // f==d2 true
        System.out.printf("float(d)==f %b\n", (float)d==f); // float(d)==f true
    }
}

 

1. d==f 비교

d == f

-> d == (double) f

-> 0.10000000000001 == (double) 0.1000000149011612

-> 0.10000000000001 == 0.1000000149011612

-> false

 

2. d2==f 비교

double d2 = (double) f;

-> double d2 = (double)  0.1000000149011612;

-> d2 =  0.1000000149011612;

 

d2 == f

-> 0.1000000149011612 == 0.1000000149011612

-> true

 

float과 double 타입을 비교하려면 double타입을 float타입으로 형변환후 비교해야한다.

 

3. d2==f 비교

(float) d == f

-> (float) 0.10000000000001 == 0.1000000149011612

-> 0.1000000149011612 == 0.1000000149011612

-> true

 

* 주의할 점: 문자열 비교

두 문자열을 비교할 때는 비교 연산자 대신 equals()라는 메서드를 사용해야 한다.

 

 

2-4. 논리 연산자

연산자 이름
&& 그리고
|| 또는
! 부정

 

 

코드예제

int a = 9;

System.out.printf("a는 1이상 그리고 10이하이다  = %b\n", 1<=a && a<=10);
//a는 1이상 그리고 10이하이다  = true

System.out.printf("a는 1이상 또는 -100미만이다.  = %b\n", 1<=a || a<-100);
//a는 1이상 또는 -100미만이다.  = true

System.out.printf("a는 9가 아니다. = %b\n", !(a == 9));
//는 9가 아니다. = false

 

 

* 참고

논리 연산자는 왼쪽부터 판단한다. 만약 왼쪽에 있는 것을 판단했을 때, 결과를 도출할 수 있다면 그 다음 부분들은 판단하지 않는다.

 

 

2-5. 비트 연산자

피연산자를 이진수로 표현 후 비트단위로 논리 연산을 한다.

비트연산자
|(OR 연산자) 피연산자 중 한쪽이라도 1이면 1을 결과로 얻는다. 그 외는 0을 얻는다.
&(AND 연산자) 피연산자 모두 1이면 1을 결과로 얻는다. 그 외는 0을 얻는다.
^(XOR 연산자) 피연산자의 값이 서로 다를 때만 1을 결과로 얻는다. 같을 때는 0을 얻는다.
~(! 연산자) 0은 1로, 1은 0으로 바꾼다.
<<,>>(쉬프트 연산자) 이진수를 이동

 

|(OR 연산자)

주로 특정 비트의 값을 변경할 때 사용한다.

 

&(AND 연산자)

주로 특정 비트의 값을 뽑아낼 때 사용한다.

 

^(XOR 연산자)

보통 간단한 암호화에 사용된다.

 

코드예제

int x = 0xAA, y = 0xE;

System.out.printf("x = %#X  \t\t[%16s]\n", x, toBinaryString(x));
//x = 0XAA  	[        10101010]

System.out.printf("y = %#X  \t\t[%16s]\n", y, toBinaryString(y));
//y = 0XE  	[            1110]

System.out.printf("%#X | %#X = \t[%16s]\n", x, y, toBinaryString(x|y));
//0XAA | 0XE = 	[        10101110]  x의 뒤의 4자리가 y로 바뀜

System.out.printf("%#X & %#X = \t[%16s]\n", x, y, toBinaryString(x&y));
//0XAA & 0XE = 	[            1010] x의 4자리가 1010이라는 것을 알 수 있음

System.out.printf("%#X ^ %#X = \t[%16s]\n", x, y, toBinaryString(x^y));
//0XAA ^ 0XE = 	[        10100100] y를 키로 암호화되었음

 

~(! 연산자)

부호 있는 타입의 피연산자는 부호가 반대로 변경된다. 1의 보수 연산 

이를 활용해 음수를 구할수도 있다. (1의 보수 + 1 = 2의 보수)

 

코드예제

byte p = 11;

System.out.printf("p = %d     [%32s]\n", p, toBinaryString(p));
//p = 11     [                            1011]

System.out.printf("~p = %d   [%16s]\n", ~p, toBinaryString(~p));
//~p = -12   [11111111111111111111111111110100]

System.out.printf("~p+1 = %d [%16s]\n", ~p+1, toBinaryString(~p+1));
//~p+1 = -11 [11111111111111111111111111110101]

 

<<,>>(쉬프트 연산자)

 

x<<n은 x*2 ^n과 같고

x>>n은 x/ 2^n과 같다.

 

예를들어 2 << 2는 왼쪽 피연산자인 10진수 2를 2진수로 변환하고, 왼쪽으로 2자리 이동시키는 것이다.

 

System.out.println(8 << 2);
//00100(2) 8 
//10000(2) 32
//32

 

 

2-6. 그 외 연산자

?연산자

조건식 ? 식1 : 식2

조건식의 결과에 따라 다른 결과를 반환하는 연산자.

 

코드예제

int x = 3;
int y = 4;
boolean result = (x==y)? true : false;
System.out.println("result = " + result);
//result = false

x==y로 조건을 만족하므로 식1인 true를 반환한다.