Java

연산자

연산자란

연산자(演펴다연 算계산산 子, operator)란 특정한 작업을 하기 위해서 사용하는 기호를 의미한다. 작업의 종류에 따라서 대입 연산자, 산술 연산자, 비교 연산자, 논리 연산자 등이 있다. 이번 수업에서는 가장 기초적인 연산자에 대해서 알아보고, 여기서 다루지 않는 연산자들은 각 연산자가 실제로 사용되는 맥락에서 차차 알아보겠다.

산술 연산자

산술(算셈산 術재주술, Arithmetic)연산자는 수학적인 계산에 사용되는 연산자다. 기초적인 수학적 소양이 있다면 어려운 연산자는 없다. 다만 수학에서 사용하는 연산자와 프로그래밍에서 사용하는 연산자는 기호의 모양이 조금 다르다.
아래 표를 보자.

+ 더하기
- 빼기
* 곱하기
/ 나누기
% 나머지

노란색으로 표시된 부분이 프로그래밍과 수학의 기호가 다른 연산자들이다.  연산자들의 사용법을 예제를 통해서 알아보자. (실행)

package org.opentutorials.javatutorials.operator;

public class ArithmeticDemo  {
    public static void main(String[] args) {
        // result 의 값은 3
        int result = 1 + 2;
        System.out.println(result);
 
        // result 의 값은 2
        result = result - 1;
        System.out.println(result);
 
        // result 의 값은 4
        result = result * 2;
        System.out.println(result);
 
        // result 의 값은 2
        result = result / 2;
        System.out.println(result);
 
        // result 의 값은 10
        result = result + 8;
        // result 의 값은 3
        result = result % 7;
        System.out.println(result);
    }
}

결과는 아래와 같다.

3
2
4
2
3

연산자 중에 다소 난이도가 있는 나머지에 대해서 알아보자. (실행)

package org.opentutorials.javatutorials.operator;

public class RemainerDemo {
    public static void main(String[] args) {
        int a = 3;
        System.out.println(0%a);
        System.out.println(1%a);
        System.out.println(2%a);
        System.out.println(3%a);
        System.out.println(4%a);
        System.out.println(5%a);
        System.out.println(6%a);
    }
}

결과는 아래와 같다.

0
1
2
0
1
2
0

나머지는 오른쪽의 피연산자의 값을 왼쪽의 피연산자의 값으로 나누었을 때 나머지 수를 의미한다. 나머지에 대해서 잘 모르겠다면 중학 수학 강의를 참고하자. 결과를 자세히 보면 재미있는 규칙성을 발견할 수 있다. 숫자가 0~2를 단위로 순환하고 있다. 나머지를 이용하면 수가 증가함에 따라서 규칙적으로 순환하는 값을 만들 수 있다. 지금 단계에서 중요한 내용은 아니다.

+ 연산자는 숫자와 숫자를 더할 때 사용되지만, 문자열과 문자열을 결합할 때도 사용된다. 아래의 예제를 보자. (실행)

package org.opentutorials.javatutorials.operator;

class ConcatDemo {
    public static void main(String[] args){
        String firstString = "This is";
        String secondString = " a concatenated string.";
        String thirdString = firstString+secondString;
        System.out.println(thirdString);
    }
}

결과는 다음과 같다.

This is a concatenated string.

그럼 조금 복잡한 사례를 접해보자. 자바는 데이터 타입이 있기 때문에 같은 숫자임에도 정수와 실수라는 형식이 존재한다. 그럼 타입별로 나누기한 결과는 어떻게 될까? (실행)

package org.opentutorials.javatutorials.operator;

public class DivisionDemo {
     
    public static void main(String[] args) {
        int a = 10;
        int b = 3;
         
        float c = 10.0F;
        float d = 3.0F;
         
        System.out.println(a/b);
        System.out.println(c/d);
        System.out.println(a/d);
         
    }
 
}

결과는 다음과 같다.

3
3.3333333
3.3333333

첫 번째 결과는 정수와 정수를 나눈 것이다. 3은 나머지의 몫이고, 나머지는 버려졌다. 정수는 소수점을 표현할 수 없으므로 정수만 표시된 것이다.

세 번째 결과는 정수에서 실수를 나눈 것이다. 이 경우 암시적으로 형 변환이 일어나기 때문에 정수가 실수가 된다.

단항 연산자

1+2에서 사용한 연산자 +는 이항(二두이 項항목항, infix operator) 연산자이고, 좌항인 1과 우항인 2를 더해주는 작업을 하고 있다. 단항(單홑단 項항목항, unary) 연산자는 하나의 항을 대상으로 연산이 이루어지는 연산자이다. 다음은 자바에서 제공하는 단항 연산자들이다.

+ 양수를 표현한다. 실제로는 사용할 필요가 없다.
- 음수를 표현한다.
++ 증가(increment) 연산자로 항의 값을 1씩 증가 시킨다.
-- 감소(Decrement) 연산자

아래는 단항 연산자들을 사용한 예제다. (실행)

package org.opentutorials.javatutorials.operator;

public class PrePostDemo {
    public static void main(String[] args) {
        int i = 3;
        i++;
        System.out.println(i); // 4 출력
        ++i;
        System.out.println(i); // 5 출력
        System.out.println(++i); // 6 출력
        System.out.println(i++); // 6 출력
        System.out.println(i); // 7 출력
    }
}
4
5
6
6
7

3행을 보면 i의 값이 3이다. 4행에서 i++를 한 후에 5행에서 출력한 결과는 4가 되었다. ++는 자신과 결합되어 있는 항의 값에 1을 더하는 연산을 한다. 이것은 아래와 의미가 같다. 자주 사용되는 연산이기 때문에 축약된 형태로 지원하는 것이다.

i = i + 1;

6행은 4행과 다르게 ++가 i 앞에 나왔다. 결과는 5다. ++가 i의 앞에 붙은 것이나 뒤에 붙은 것이나 결과는 같은 것 같다. 하지만 8행의 결과는 6이고, 9행의 결과값도 6이다. 무언가 이상하다. ++i는 i의 값에 1이 더해진 값을 출력하는 것이고, i++는 이것이 속해있는 println에 일단 현재 i의 값을 출력하고, println의 실행이 끝난 후에 i의 값이 증가하는 특성이 있다. 중요한 내용은 아니다. 이해가 안되면 일단 넘어가자.

연산의 우선순위

실제로 프로그래밍을 하게 되면 다양한 연산자들을 복합적으로 사용하게 된다. 이럴 때 연산의 선후 관계가 분명하지 않으면 혼란스러울 것이다. 아래는 자바에서 제공하는 연산자들 간의 우선순위를 정리한 표이다.

우선순위 연산자 결합방향
1 [ ]
()
.
2 ++
--
+(양수) -(음수)
~
!
(type)
new
3 * / %
4 +(더하기) -(빼기)
+(문자 결합 연산자)
5 <<
>>
>>>
6 < <=
> >=
instanceof
7 ==
!=
8 &
&
9 ^
^
10 |
|
11 &&
12 ||
13 ? :
14 =
*= /= += -= %=
<<= >>= >>>=
&= ^= |=

위의 표를 보는 방법을 알아보자. 아래를 계산해보자.

int a = 4-3*6;

위의 구문에는 3가지의 연산자가 등장한다. =, -, * 이다. 표에 따라서 우선순위 별로 배열해보면 *, -, =가 된다. 그러므로 연산자 *가 제일 먼저 실행된다. 따라서 첫 번째 연산은 3*6이 된다. 그 값은 18이다. 그다음 우선순위는 -다. 4-18을 해야 하는데 빼기의 결합 방향은 →이다. 따라서 4에서 18을 빼야 한다. 그 결과는 -14가 된다. 그다음 우선순위는 대입 연산자인 '='이다. '='의 결합방향은 '←'이기 때문에 -14를 변수 a에 대입해서 연산이 끝나게 된다. 

위의 표를 외울 필요는 없다. 자연스럽게 이해하게 된다. 다만, 헷갈리는 경우가 있을 때 이 표의 도움을 받도록 하자.

댓글

댓글 본문
작성자
비밀번호
  1. 조아
    "중학 수학 강의"동영상을 보니 "저걸 언제 배웠었나?" 하는 생각이 드네요.ㅋㅋㅋ
  2. ljn425
    감사합니다.
  3. Ryan.L
    감사합니다.!
  4. 정명호
    감사합니다
  5. 500번째 시청자네요.
    생활코딩을 통해서 뇌지도를 다시 작성하는 기분입니다.^^
    감사합니다.
  6. JustStudy
    고맙습니다
  7. 주지스
    결합 방향이 연산 방향과 같은 건가요?
    그러니까 예를 들자면, 삼항 연산자는 세 개의 항의 값을 을 차례대로 우측부터 읽어오는 건가요?
  8. yskioi
    감사합니다.
  9. Devani0310
    감사합니다
  10. 오빠는다르다
    감사합니다!!!!
  11. Byunghawk Lee
    못보던 연산자도 있네요 >>> 비트 연산같은데??
    흠 이건 어땋게 사용되는 지는 천천히 공부해 보겠습니다.
    다음으로....
  12. 현팡
    정주행중입니다
  13. 허니버터
    잘보고 갑니다
  14. Esunny
    출력 값은 1입니다.

    int c=0;
    System.out.println(c---c);
    System.out.println(c-(--c));

    아래 코딩과 동일하게 실행되는 것 같습니다.
    대화보기
    • Creator
      나머지는 오른쪽의 피연산자의 값을 왼쪽의 피연산자의 값으로 나누었을때 나머지를 의미한다를 나와있는 코드에 대입해서 이해해서 한참을 당황했네요. 예를들어 5%a 면 a가 3이고 오른쪽에 위치하니 3나누기 5로 생각해서 한참 삽질을 ㅠㅠ 일일히 다 계산해보고 나서야 제가 굉장히 창의적인 발상을 했구나... 싶은 생각이..ㅎㅎ
    • holy
      int i=0;
      System.out.println( i---i );
      //결과가 몇이 나오고 왜 그런지 설명해보세요 ^^
    • holy
      int i=0;
      System.out.println(i);
      i = ++i;
      //1=1
      System.out.println(i);
      i = ++i + ++i;
      //5=2+3
      System.out.println(i);
      i = i++ + i++;
      //11=5(6)+6(7)
      System.out.println(i);
      i = i++ + i++ + i++;
      //36=11(12)+12(13)+13(14)
      System.out.println(i);
    • 왕초보
      외우는건 머리를 혹살시키는겁니다!!!!
    • 시나본
      앜ㅋㅋㅋ 중학수학 깨알링크 ㅎㅎ감사합니다.
    • ssarl
      중학 수학 강의까지 링크 걸어주시는 센스 ㅋㅋㅋㅋ
    • 철구
      감사합니다
      대화보기
      • Akinaro
        나머지 = remainer <- X 틀렸습니다. 저런 단어 없습니다.ㅋㅋ
        나머지 = remainder <- O 이게맞습니다. ㄴ d가 빠지셨네요. ㅋㅋ
        영어단어 나오면 좀 더 이해를 쉽게 하기위해 검색을 했는데 remainder 이더군요. ㅎㅎ
      • 증감연산자 참고
        증감연산자(++, --)는 변수에 저장된 값을 1 증가 또는 1 감소 시키는데
        변수의 어느 쪽에 위치 하느냐에 따라 다른 값을 반환합니다.

        전위(prefix): 증가 또는 감소가 이루어 진 뒤 바로 그 값을 반환합니다.
        후위(postfilx): 증가 또는 감소가 이루어 진 뒤 그 이전의 값을 반환합니다.
      • 환글
        자세하고 친절한 강의로 귀에 쏙쏙 들어 오네요^^ 고맙습니다.
      • 샤핀
        그렇군요. ㅎㅎ. 더 짧게 빠르게 프린트라인을 쓸 수 있겠네요. ㅋ
        감사합니다.
        대화보기
        • moby
          대단히 감사합니다.
          대화보기
          • moby
            // result 의 값은 10
            result = result + 8;

            여기서

            System.out.println(result);

            빠뜨리셨네요 ㅎㅎ

            got ya! ^오^
          • old 막내
            syso 만 입력해도 바로 적용 되더군요. ^^
            대화보기
            • old 막내
              중간 설명에 중학 수학 강의 참조 눌렀는데 진짜 동영상 강의 나왔을 때 빵 터졌습니다. ㅋㅋㅋㅋㅋ
            • 라파
              오 좋은거 배우게 되네요 신기방기+_+
              대화보기
              • 토닥
                주석과 세미콜론 강의를 보다가... 도트연산자에 대한 댓글을 보고 공감이 들어서, 이곳으로 댓글 달러 왔습니다~

                간단히 예를 들어, System.out.println을 보면 사이사이에 찍혀있는 점(.)들. 이것도 연산자인데요, 이름은 도트연산자라고 합니다~
                [연산 대상의 내부 자원으로 접근하는 연산자]입니다. "나 들어갈게~"하는 의미로 똑, 노크한다고 생각하세요.
                그치만 '똑똑~'하고 남의 집을 들어가도, 아무데나 헤집고 다니진 못하잖아요? 상대가 들여보내주는 곳만 들어갈 수 있죠.
                그것도 마찬가지입니다. '접근'하는 연산자니까 '접근 가능한' 자원에만 접근할 수 있습니다.
                자세한 사항은 접근제어자 수업에서!

                자꾸 접근접근하니까 게슈탈트가 붕괴되네요....ㅋㅋㅋ
                이로써 짧은 지식 나누기 끝.
              • Haewon Lee
                오 조아조아
                대화보기
                • 밤은추워
                  샤핀//자바 매크로도 알아둬야겠어요ㅎㅎ
                • egoing
                  오 그렇구요!
                  대화보기
                  • 샤핀
                    이쯤보다 보니 혹시 알고 계실 지 모르지만 강좌 보시는 분들을 위한 Tip하나.
                    System.out.println(); 이 부분 이클립스에서 일일히 치려면 손이 많이 가는데..
                    sysout 라고 치시고 Ctrl + Space 키 치시면

                    System.out.println(); <-- 이 구문이 자동완성 됩니다.

                    더 알고 싶으실 땐 구글에 이클립스 자바 매크로 라고 쳐보시면 됩니당 ^^
                  • 늦장공부
                    중학 수학강의 까지 찾아서 링크해 주시고
                    세심한 손길이 느껴집니다.
                  • 왕초보
                    논리연산자 (의미 : 또는)
                    a | b
                    a || b

                    무슨 차이가 있을까?
                    둘 다 같은 의미이다.
                    하지만 (차이점) a|b 는 a, b의 값을 평가한다. 즉, a 가 참이라도 b 를 검사한다.
                    a||b 의 경우 a 가 참이면 b를 검사하지 않는다. 즉 b 가 단항연산자(++ ,-- 등) 이 있어 검사할 경우와 그렇지 않을 경우에 결과에 차이가 있다.


                    마찬가지로 &, && 에도 비슷하다.

                    추가로
                    &, | 는 논리연산자로만 사용하는 것이라 아니라 비트연산자로도 사용한다.
                    a&b : 비트단위의 논리곱
                    a|b : 비트단위의 논리합
                  • 그렇다고합니다
                    &&랑 &, ||랑 |는 무슨 차이가 있는 건가요?
                  버전 관리
                  egoing
                  현재 버전
                  선택 버전
                  graphittie 자세히 보기