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. ozic
    3번째 독..완료
  3. 멀캠A_Son
    완료
  4. 이태호
    6/27
  5. asdzxc1822@naver.com
    clear
  6. asdzxc1822@naver.com
    clear
  7. 감사합니다
  8. 드론
    오.. 해보니까 되네요. 이렇게도 쓸 수 있군요!


    JAVA님의 질문처럼, "정수/정수 = 실수"로 결과값을 얻고 싶을 때
    즉, 딱 떨어지지 않는 정수 int형 데이터끼리 나눌 때, "소수점 이하자리 데이터가 손실되는 문제없이"
    "실수형 데이터 값으로 출력하려면" 어떻게 해야 될까? 란 호기심을 해결하는

    아이디어 중 하나는 enjoygorani님의 답변과 같이

    1. 명시적 형변환

    - https://ideone.com/0uI3z9 (enjoygorani님이 주신 답변을 제가 Ideone.com에서 작성 후 출력해봤습니다.)

    - https://ideone.com/ZCowDf (float 와 마찬가지로 double 도 실수형 데이터 타입이고, 따라서 윗 링크와 같은 논리로 (double)로도 명시적 형변환을 시켜봤어요.)

    enjoygorani님의 답변처럼 강의에서 배운 "명시적 형변환" 을 활용해 해결할 수 있다는 것!
    댓글을 통해 저도 하나 더 배워가네요!

    그리고 여기에 저도 두번째 아이디어를 덧붙입니다!
    바로 "자동 형변환"을 활용하는 것입니다.


    2. 암시적 형변환 (자동 형변환)

    "자동 형변환은 데이터손실이 일어나지 않는 쪽으로 암묵적으로 이뤄진다.
    따라서 수 표현이 간단한 쪽(정수)이 자세한 쪽(실수)으로 변환돼야 한다"

    변수를 double타입인 실수형 데이터로 지정하자

    이 아이디어를 코드로 작성한 것이 아래와 같습니다.

    double a = 10;
    double b = 3;
    System.out.println(a/b);

    다시 말해, JAVA님의 작성코드 중
    아래 부분을 수정해 자동적 형변환이
    이뤄지는 방식입니다

    int a = 10;
    int b = 3;

    우변에 놓인 "정수 10과 3이"
    변수 a, b에 각각 담기게 될 때, "실수 10.0과 3.0으로" 담기려면 어떻게 해야 될까?
    그럼 a/b 나눈 연산결과가 실수가 될텐데?
    => 올커니~ 좌변에 놓인 "변수 a, b 의 데이터 타입 지정 시 double 타입의 "실수형 데이터 변수로 지정"하면 되겠구나!

    double a = 10;
    double b = 3;

    즉 위처럼 수정하면
    정수 10과 3이 변수에 담길 때 a=10.0, b=3.0처럼 실수형으로 "자동적 형변환"이 이뤄지죠.

    System.out.println(a/b);의
    출력 결과는 아래 링크에서 볼 수 있습니다.

    - https://ideone.com/Iq4Vo9
    대화보기
    • 드론
      우리 강사님이 무슨 일을 하시든 잘되셨으면 좋겠습니다

      강의 대단히 감사드립니다
    • 복 받으실 꺼에요~ 감사합니다.
    • 4월 24일 연산자
    • 송영일
      4월24일 잘보았습니다
    • 박현모
      감사합니다~
    • 열정하나
      4월 18일 여기까지~
    • ㅎㅎ
      훗훗 다음은 비교닷!
    • 4/9
    • 김예슬
      180311
      + 더하기, 문자의 결합. - 빼기. / 나누기. * 곱하기. % 나머지
      정수/정수=정수 , 실수/실수=실수 , 정수/실수=실수 (계산해야하는 변수가 서로 다른 데이터타입이라면 더 자세하고 조밀한 데이터 타입으로 자동변환된다. 실수가 정수보다 조밀함)
      단항연산자 ++. --
      연산자의 우선순위 는 알고있는 지식내에서 ! 잘!
    • 이근환
      연산의 우선순위는 몰랐는데 이런게 있다는 걸 알게되었습니다!!
      감사합니다!!:)
    • 2차
    • kokuny
      完了
    • 반자동
      안드로이드 앱 프로그래밍을 위해 기초를 다지는중입니다.. 이번에도 클리어
    • 개발자 픽스
      안녕하세요 개발자 픽스입니다. 강의가 안드로이드 앱 프로그래밍에 많은도움이되네요
    • nx5022
      이해가 넘나 잘되네요~
    • 2017/11/22
    • JeongHo Park
      잘 봤습니다~~감사합니다.
    • GoldPenguin
      감사합니다.
    • 수강완료.!
    • 11월 5일출



    • 티알븨
      2년 전에 내신 문제에 대한 답입니다!
      int i=0;//i 값에 0 부여.
      System.out.println(i---i);//i(0)- --i(-1)
      즉, 첫번째 i는 0의 값을 가지고 있고, 바로 뒤의 -는 빼기를 뜻하는 연산자 입니다.
      두번째 i는 앞의 --를 받고 -1이 됩니다.
      따라서 0 - (-1)이 되므로 1이 나오게 됩니다.
      대화보기
      • 두꽁
        777
      • xlcncrd
        ArithmeticDemo 에서는 계산식이 내려 갈 때마다 result값이 변하는대, RemainerDemo에서는 계산식이 내려가도 a값이 3으로 고정되어 있는 것은 왜 그런지요?
        첫번째 예에서
        result =
        result = result - 1
        result = result * 2
        .
        .
        .
        내려 갈 때마다 result값이 갱신되는 것인지요?
      • ywChoi
        감사합니다!
      • rain98
        실수형 변수를 하나 더 지정하시면 될 꺼에요...

        int a = 10;
        int b = 3;
        float c;
        c = a/b;

        System.out.println(c);
        대화보기
        • yoon88
          완료
        • enjoygorani
          저도 잘은 모르지만 ㅠ
          왠지..

          int a = 10;
          int b = 3;

          System.out.println((float)a/(float)b);

          요렇게하면 되지않을까요??;;
          대화보기
          • 저 형변환2/4강의에서요
            int a = 10;
            int b = 3; 이고
            System.out.println(a/b)를하게되면 3이출력되잖아요
            여기서 문제가발생하는건 3이라는 정수가 출력되기떄문에 뒤에소수점(실수)자리를 생략하는 문제가발생하는데
            어떻게 해결하나요 정수 / 정수 = 정수인데 정수/ 정수 = 실수라는값을 얻고싶을때 JAVA에선 어떻게 해야하나요
          • 가나다
            답을 드리자면
            계산해야 할 부분은 i---i 이지요?

            근데 연산자 우선순위 때문에 2(i-) 1(--i)
            1 -> 2의 순서로 계산이 됩니다. 여기에 i를 대입하면
            0- --1 => 0-(-1) 이 되겠죠?

            마이너스가 두번이기 때문에 최종값은 1이됩니다.
            대화보기
            • int i = 0;
              System.out.println(i---i);
              //1

              i---i = i--(-i) = 0(여기에서 i가 -1만큼 변함) - (-1) = 0 - (-1) = 0 + 1 = 1
              대화보기
              • 모가비
                30대 후반에 10년도 전에 손 놓은 코딩 다시 배우기 힘드네요.ㅜㅠ
              • 미림_likelion
                수강완료했습니다. 감사합니다.
              • 강재원
                앙 기모띠
              • answer
                System.out.println( i---i );
                //1
                System.out.println((i--)-i);
                // 0(-1) - (-1)
                값은 1이 도출 되었습니다.
                이렇게 되어서 값이 1이 나오는건가요??
                대화보기
                • 고현우
                  외우는건 뇌를 혹사시키는 것이다 오오오오
                • yosim
                  역시 계산은 어렵네요
                • J_Project
                  감사합니다.
                • InSoo
                  170315
                  감사합니다.
                • 김인섭
                  감사합니다^^
                • 오오
                  감사합니다
                • 내이름은이한샘
                  잘봤습니다.!! 이고잉선생님 새해 복 많이 받으세요.!
                • 밑의문제도 잘풀고갑니당
                버전 관리
                egoing
                현재 버전
                선택 버전
                graphittie 자세히 보기