[JAVA] 연산자의 개념과 종류

dejeong·2024년 9월 6일
0

JAVA

목록 보기
6/24
post-thumbnail

연산자와 연산식

연산식은 하나의 값을 산출하며, 연산자 수가 아무리 많아도 두 개 이상의 값을 산출하는 연산식은 없다. 즉, 연산식은 항상 단일한 결과를 생성한다.

구분연산자비고
결과가 boolean숫자 비교 연산자<, <=, >, >=
숫자 동등 연산자==, !=
결과가 int 혹은 long기본 사칙 연산자+, -, *, /, %
증감 연산자++, --
비트 연산자&,, ^, ~, <<, >>, >>>
기타 연산자삼항 연산자? :
형 변환 연산자(타입)
문자열 더하기 연산자+

연산의 방향과 우선순위

연산자 중 증감, 부호, 비트, 논리 연산자가 우선순위가 가장 높으며, 대입 연산자의 우선순위가 가장 낮다. 대부분의 연산은 왼쪽에서 오른쪽 방향으로 계산된다.

연산의 순서를 명확히 하기 위해, 본인이 원하는 연산 순서대로 소괄호로 묶어서 명시적으로 표현하는 것이 좋다. 한 라인에 많은 연산이 포함되어 가독성이 떨어진다면, 연산식을 적절히 분리하는 것도 좋은 습관이다.


단항 연산자

  • 부호 연산자(+,-) 양수나 음수를 표시하는 +-가 있다. 이 연산자는 변수값의 부호를 유지하거나 바꾸기 위해 사용된다.
  • 증감 연산자(++,--) 변수값을 1 증가(++)시키거나 감소(--)시키는 연산자이다. boolean을 제외한 모든 기본 타입의 피연산자에 사용할 수 있다. [증감 연산자 종류]
    • ++피연산자(전위 증감 연산자) : 다른 연산을 수행하기 전에 피연산자의 값을 1 증가시킴.
    • -피연산자 : 다른 연산을 수행하기 전에 피연산자의 값을 1 감소시킴.
    • 피연산자++(증가 후위 연산자) : 값을 먼저 읽어온 후에 피연산자의 값을 1 증가시킴.
    • 피연산자--(감소 후위 연산자) : 값을 먼저 읽어온 후에 피연산자의 값을 1 감소시킴.
  • 논리 부정 연산자(!) 논리 부정 연산자는 truefalse로, falsetrue로 변경한다. 이 연산자는 boolean 타입에만 사용할 수 있으며, 조건문이나 제어문에서 조건식의 값을 부정할 때 사용되어 실행 흐름을 제어한다. 또한, 토글(Toggle) 기능 구현 시에도 주로 사용된다.
    int x = 1;
    int y = 2;
    boolean result = !(x + y > 5); // x + y가 5보다 큰지 확인한 후 결과를 반대로 변경.
  • 단항연산자 - 증감 전/후위 연산자 예제
    public class Sample {
        public static void main(String[] args) {
            // 단항연산자 - 증감 전/후위 연산자
            int x = 5;
            int result = x--;
            System.out.println(result); // 5
            System.out.println(x); // 4
    
            int x1 = 14;
            int result1 = --x1;
            System.out.println(result1); // 13
            System.out.println(x1); // 13
    
            int x2 = 14;
            int result2 = --x2;
            System.out.println(result2); // 13
            System.out.println(x2++); // 13
    
            int x3 = 5;
            int result3 = x3++ + 3;
            System.out.println(result3); // 8
    
            int result4 = x3;
            System.out.println(result4); // 6
        }
    }
  • 전위 증감 연산자와 후위 증감 연산자 예제
    public class IncreaseDecreaseOperatorExample {
        // 전위 증감 연산자와 후위 증감 연산자
        // 후위 연산자는 다음 호출 때 적용된다고 생각
        public static void main(String[] args) {
            int x = 10;
            int y = 10;
            int z;
    
            System.out.println("----------------------");
            x++; // 11
            ++x;
            System.out.println("x=" + x); // 12
    
            System.out.println("----------------------");
            y--; // 10
            --y; // 9 -> 9 - 1
            System.out.println("y=" + y); // 8
    
            System.out.println("----------------------");
            z = x++; // 12
            System.out.println("z=" + z); // 12
            System.out.println("x=" + x); // 13
    
            System.out.println("----------------------");
            z = ++x; // 14
            System.out.println("z=" + z); // 14
            System.out.println("x=" + x); // 14
    
            System.out.println("----------------------");
            z = ++x + y++; // 23 = 15 + 8
            System.out.println("z=" + z); // 23
            System.out.println("x=" + x); // 15
            System.out.println("y=" + y); // 9
        }
    }
    
  • 논리 부정 연산자 예제
    public class DenyLogicOperatorExample {
        // 논리 부정 연산자
        public static void main(String[] args) {
            boolean play = true;
            System.out.println(play);
    
            play = !play;
            System.out.println(play);
    
            play = !play;
            System.out.println(play);
        }
    }

이항 연산자

  • 산술 연산자(+, -, , /, %) 피연산자들의 타입이 (byte, int, long, double, …) 동일하지 않다면, 아래와 같은 규칙에 따라 연산이 수행된다.
    • 피연산자들이 모두 int보다 크기가 작을 경우 int로 변환 후 연산
      • 예: byte + byte → int + int
      • 자동 형변환 예시:
        byte x = 45;
        byte y = 67;
        
        int result = x + y;  // 정상적으로 연산
        byte result2 = x + y;  // 에러 발생, x와 y가 자동으로 int로 형변환되기 때문에 에러 발생
        // byte 형태로 저장하려면 명시적 캐스팅 필요
        byte result2 = (byte)(x + y);
    • 피연산자 중에 long 타입이 있을 경우 모두 long으로 변환 후 연산
      • 예: int + long → long + long
      • 예시:
        int x = 100;
        long y = 200L;
        
        long result = x + y;  // 자동으로 long으로 변환되어 정상적으로 연산
    • 피연산자 중에 float 혹은 double 타입이 있을 경우 크기가 큰 실수 타입으로 변환 후 연산
      • 예: int + float → float + float

      • 예시 :

        int x = 40;
        float y = 50.34F;
        
        float floatResult = x + y;  // 정상적으로 연산, float으로 자동 형변환
        int intResult = (int)(x + y);  // 캐스팅 필요

        주의사항: intfloat 모두 4바이트 크기를 가지지만, 실수 타입이 표현할 수 있는 범위가 더 크기 때문에 연산 시 실수 타입이 우선시된다.

        int x = 40;
        double y = 50.34;
        
        double doubleResult = x + y;  // 40.0 + 50.34
        int intResult = (int)(x + y);  // 결과값은 90으로 소수점이 버려짐
  • 오버플로우 데이터 타입이 저장할 수 있는 범위를 초과할 때 발생한다. 이 경우 결과값은 예상하지 못한 엉뚱한 값으로 나타나며, 이는 프로그래밍 시 주의해야 할 사항이다.
  • NaN, Infinity NaN (Not a Number)과 Infinity는 실수 타입 연산 중 특정 조건에서 발생할 수 있다.
    주로 0이 피연산자로 사용될 때 나타난다.
    • NaN은 0을 0으로 나누거나 0을 제외한 다른 숫자와 연산하여 생긴다.

    • Infinity는 0이 아닌 수를 0으로 나눌 때 나타난다.

      이 값들이 연산 결과로 나오면, 이후 연산에서는 NaN이나 Infinity가 계속 전달되기 때문에 다음 연산을 수행하지 않도록 주의해야 한다.

      double a = 10;
      double b = 0;
      
      System.out.println(a / b);  // 출력: Infinity
      System.out.println(a % b);  // 출력: NaN
      
      // NaN, Infinity 확인 방법
      System.out.println(Double.isInfinite(a / b));  // 출력: true, is ~ : 결과가 boolean
      System.out.println(Double.isNaN(a % b));  // 출력: true, b에 0이 아닌 값이 들어가면 false로 출력

      isInfinite, isNaN 메서드를 사용하여 InfinityNaN 값을 확인할 수 있다.
      이는 boolean 값으로 반환되며, 연산 과정에서 예외 처리를 할 때 유용하게 사용된다.

  • 문자열 연결 연산자(+) + 연산자는 산술 연산자이면서 동시에 문자열 연결 연산자로도 사용된다.
    피연산자 중 하나가 문자열일 경우, 다른 피연산자는 자동으로 문자열로 변환되어 결합된다.
    System.out.println("Hello" + 123 + 456);  // 출력: Hello123456
    System.out.println(123 + 456 + "Hello");  // 출력: 579Hello
  • 비교 연산자 (<, <=, >, >=, ==, !=)

    두 피연산자를 비교하여 결과를 boolean 타입인 true 또는 false로 산출한다.
    주로 조건문에서 사용되며, 다양한 비교 방식이 가능하다.

    • 크기 비교:
      • A > B : A가 B보다 큰지 검사
      • A >= B : A가 B보다 크거나 같은지 검사
      • A < B : A가 B보다 작은지 검사
      • A <= B : A가 B보다 작거나 같은지 검사
    • 동등 비교 :
      • A == B: A와 B가 같은지 검사
      • A != B : A와 B가 다른지 검사
  • 논리 연산자 (&&, ||, &, |, ^, !)

    boolean 타입의 피연산자를 다루며, 주로 조건식을 연결하거나 비교할 때 사용된다.
    결과값도 boolean 타입이다.

    • AND (&&) : 두 피연산자가 모두 true일 경우에만 결과가 true

    • OR (||) : 피연산자 중 하나라도 true이면 결과는 true

    • XOR (배타적 논리합, ^) : 피연산자가 하나는 true이고 다른 하나는 false일 경우에만 결과가 true

    • NOT (논리 부정, !) : 피연산자의 논리 값을 반전시킴. truefalse로, falsetrue

      boolean a = true;
      boolean b = false;
      
      boolean result = a && b;  // false
      boolean result = a || b;  // true
      boolean result = a ^ b;  // true
      boolean result = !a;  // false
  • 비트 연산자 (&, |, ^, ~, <<, >>, >>>) 데이터를 비트 단위로 연산할 때 사용된다.
    int 타입이나 이와 호환되는 정수형 타입에서 사용되며, 비트 연산을 통해 다양한 비트 단위 조작을 수행할 수 있다. 비트는 0과 1로 이루어져 있으며, 이러한 연산은 주로 저수준의 비트 조작이 필요할 때 유용하다.
    • 예제 코드

      ```java
      public class BitOperator {
          public static void main(String[] args) {
              // 비트 논리 연산자
              int x = 15;
              int y = 30;
      
              System.out.println(x & y);
              System.out.println(x | y);
              System.out.println(x ^ y);
              System.out.println(~x);
      
              // 비트 쉬프트 연산자
              int value = 8;
              int value2 = -8;
              System.out.println(value >>> 1);
              System.out.println(value2 >> 2);
              System.out.println(value2 >>> 1); // 2147483644
          }
      }
      ```

      [비트 논리 연산자]

      &, |, ^, ~ 가 있다.
      &, |, ^ 연산자는 피연산자가 boolean이면 일반 논리 연산자이고, 피연산자가 정수이면 비트 논리 연산자로 동작한다.

    • AND (논리곱) - &: 두 비트가 모두 1일 경우에만 결과가 1

    • OR (논리합) - |: 두 비트 중 하나만 1이면 결과가 1

    • XOR (배타적 논리합) - ^: 두 비트 중 하나는 1이고 다른 하나는 0일 경우에만 결과가 1

    • NOT (논리 부정) - ~: 비트를 반전시켜 0을 1로, 1을 0으로 바꾼다.

      [비트 이동 연산자 (쉬프트 연산자)]
      정수 데이터를 좌측 또는 우측으로 비트를 밀어서 이동시키는 연산을 수행하고, 이러한 연산은 비트 수준에서 값을 빠르게 조정할 수 있는 방법을 제공한다.

    • 좌측 이동 (<<) : 정수 a의 각 비트를 b만큼 왼쪽으로 이동시키며, 빈자리는 0으로 채워진다. 비트를 왼쪽으로 이동시키면 수가 2의 b 제곱만큼 커진다.

      int x = 3; // 00011 in binary
      int result = x << 2; // 01100 in binary, 12 in decimal
    • 우측 이동 (>>) : 정수 a의 각 비트를 b만큼 오른쪽으로 이동시키며, 빈자리는 최상위 부호 비트(MSB)와 같은 값으로 채워진다. 이 연산은 부호를 유지한 채로 숫자를 2의 b 제곱만큼 나눈 것과 같다.

      int x = 12; // 01100 in binary
      int result = x >> 2; // 00011 in binary, 3 in decimal
    • 우측 이동 (부호 없는) (>>>) : 정수 a의 각 비트를 b만큼 오른쪽으로 이동시키며, 빈자리는 전부 0으로 채워진다. 부호와 관계없이 단순히 비트를 이동시킬 때 사용한다.

      ```java
      int x = 12; // 01100 in binary
      int result = x >> 2; // 00011 in binary, 3 in decimal
      ```

      이러한 비트 연산자들은 복잡한 비트 조작이 필요한 상황에서 매우 유용하며, 효율적인 데이터 처리나 특정한 알고리즘 구현에 활용될 수 있다.


삼항 연산자 (Ternary Operator)

세 개의 피연산자를 가지는 연산자로, 조건식에 따라 다른 값을 선택하는 조건 연산자이다.
간단하게 조건에 따라 값을 선택할 수 있어 코드가 짧고 간결해지지만, 복잡한 조건에서는 if문을 사용하는 것이 가독성이 더 좋다.

기본 구조

(조건식) ? 참일 때 반환 값 : 거짓일 때 반환 값;
  • 조건식: 참 또는 거짓을 반환하는 식
  • 참일 때 반환 값: 조건식이 참일 경우 반환되는 값
  • 거짓일 때 반환 값: 조건식이 거짓일 경우 반환되는 값

예제

int score = 95;
char grade = (score > 90) ? 'A' : 'B';
System.out.println("당신의 학점은 : " + grade);

동일한 로직을 if문으로 작성

public static void main(String[] args) {
    int score = 95;
    char grade;
    if (score > 90) {
        grade = 'A';
    } else {
        grade = 'B';
    }
    System.out.println("당신의 학점은 : " + grade);
}

삼항 연산자와 if문 선택
삼항 연산자는 코드를 간결하게 만들 수 있지만, 여러 조건이 복잡하게 얽혀 있을 때는 if문을 사용하는 것이 가독성 면에서 더 좋다. 상황에 따라 두 방법 중 적절한 것을 선택하여 사용하는 것이 중요하다.

  • 삼항 연산자 예제
    public class Quiz {
        public static void main(String[] args) {
            
            // 짝수, 홀수를 구분하는 코드
            int num = 67;
            
            // if문
            if(num % 2 == 0){
                System.out.println("짝수");
            }else{
                System.out.println("홀수");
            }
            
            // 삼항연산자
            System.out.println(num % 2 == 0 ? "짝수" : "홀수");
            
            /*----------------------------------------------*/
            
            // a와 b값 중 더 큰 값을 반환, 두 값이 같다면 a 반환
            int a = 40;
            int b = 20;
            
            // if문 사용
            if(a >= b){
                System.out.println(a);
            }else{
                System.out.println(b);
            }
            
            // 삼항연산자 사용
            System.out.println(a >= b ? a : b);
    				
    				/*----------------------------------------------*/
    				
            // 점수 score가 60점 이상하면 합격, 60점 미만이면 불합격을 반환
            int score = 65;
    
            if(score >= 60){
                System.out.println("합격");
            }else{
                System.out.println("불합격");
            }
    
            System.out.println(score >= 60 ? "합격" : "불합격");
        }
    }
profile
룰루

0개의 댓글