자바 연산자 우선순위(Operator Precedence)

Java 2016. 10. 18. 21:58

Java 연산자 우선순위(Operator Precedence)

우선순위(Precedence)

우선순위는 하나의 수식에 다른 종류의 연산자들이 사용되었을때, 어떤 연산자를 먼저 계산(평가)해야하는지를 정해놓은 것이다. 가령 수학에서 덧셈과 곱셈이 사용된 수식에서 무엇을 먼저 계산하는지에 따라 결과에 큰 차이를 보이게 되는데, 이 처럼 어떤 연산을 먼저 수행해야 하는지 정해놓지 않는다면 혼란이 발생하게 된다. 프로그래밍에서도 연산자의 우선순위를 명확히 해놓아 다른 의미로 계산되는것을 방지하고 있다. 만약 우선순위를 별도로 정해놓지 않았다면 모든 연산자들과 피연사자들을 일일이 괄호로 묶어야 하는 불편함이 있을 것이다.

연산자의 우선순위는 여러 프로그래밍 언어에서와 비슷한데, 대체적으로 우선순위는 이항/삼항 연사자 보다는 단항 연산자가, 복잡한 연산자 보다는 기본적이고 필수적인 연산자가, 논리적인 연산자 보다는 산술 연산자가 우선순위가 높은것을 알 수 있다.

연산자의 우선순위가 명확히 결정 되어있다 하더라도 모든 사람들이 연산자의 우선순위를 외우고 있는것은 아니므로, 자주 쓰이는 연산자의 조합이 아니라면 혼동의 여지가 있으므로 추가적인 괄호를 사용하여 명확히 해주는것이 좋은 프로그래밍 습관일 것이다.

결합방향(Associativity)

연산자의 우선순위를 결정했다 하더라도 동일한 피연산자에 같은 우선순위의 연산자들이 사용되어있다면 피연산자에 어떤 연산자들을 먼저 결합하여 처리해야 할것인가 하는 문제가 남는다.

상식적으로 같은 우선순위에 있는 덧셈과 뺄셈중 어느것을 먼저 하던지, 곱셈과 나눗셈중 어느것을 먼저 하는지에 대해 결과가 달라질 수 있는가 싶겠지만 프로그래밍 언어에서는 자료형에서 값이 표현할 수 있는 범위가 있기 때문에 여러 연속된 연산에서 중간 계산 결과에 따라 오버플로우나 언더플로우가 나타나 연산 결과에 영향을 미치는 경우가 생길 수 있다.

결합 방향을 조정해야 할 경우 괄호를 사용해서 프로그래머의 결합 방향에 대한 의도를 표현 할 수 있다.

연산자 우선순위, 결합방향 표

Description, Level, Associativity 열의 생략된 항목은 위의 가까운 값과 같다, 같은 Level을 가지는 연산자들은 같은 우선순위를 가진다

Operator Description Level Associativity
[] access array element 1 left to right
. access object member
() invoke a method
++ post-increment
-- post-decrement
++ pre-increment 2 right to left
-- pre-decrement
+ unary plus
- unary minus
! logical NOT
~ bitwise NOT
() cast 3 right to left
new object creation
* multiplicative 4 left to right
/
%
+ - additive 5 left to right
+ string concatenation
<< >> shift 6 left to right
>>>
< <= relational type comparison 7 left to right
> >=
instanceof
== equality 8 left to right
!=
& bitwise AND 9 left to right
^ bitwise XOR 10 left to right
| bitwise OR 11 left to right
&& conditional AND 12 left to right
|| conditional OR 13 left to right
?: conditional 14 right to left
= += -= assignment 15 right to left
*= /= %=
&= ^= |=
<<= >>= >>>=

2016-10-20 오후 6:13:38

'Java' 카테고리의 다른 글

자바 컴파일시 인코딩 문제  (0) 2016.10.14

설정

트랙백

댓글

프로그래밍의 과정은 수학인가?

Essay 2016. 10. 18. 01:43

오랜만에 컴퓨터 공부를 다시 시작하면서 예전엔 얼마나 열정적으로 공부를 하였던가 하는 궁금증이 생겼나서 오래전 여러 커뮤니티에 쓴 글들을 한번 살펴보았다.

첫 질문 글을 남긴것이 무려 11년전인 것으로 보아 지금의 나이에 감해보니 프로그래밍에 공부에 대한 시작이 그리 늦거나 하지는 않았던것 같다. 그럼에도 특별히 전문성을 갖추지 못한채 다른 곳에서 헤메이는 것을 보면 목표를 정하지 않고 그냥 좋아서 마구잡이로 조금씩 건들여 본것이 원인이 아니였나 싶다.

나의 질문들 중에서 가장 많은 답글이 달린 주제의 글도 유난히 눈에 띈다. 난 기억도 안나는데 제목이 참 거창하기도 하다

"프로그래밍의 과정은 수학인가?"

읽어보니 프로그래밍 문제 해결에서 직관에 많이 의존하고 것에 대한 의문이였다. 그 의문대로 직관에 의존한 프로그래밍 문제 해법은 수학이라 할 수 있을까?

프로그래밍 문제가 아니더라도 가끔 어떤 문제를 골똘히 생각하다 보면 번득이게 해법이 떠오를 때가 많고 경험이 쌓이면 이것에 좀 더 능숙해지는것 같긴하다. 이쯤되면 이게 과학적이고 수학적인 접근법인가 하는 의문이 분명히 생겨난다.

수 많은 수학자들이 스스로도 증명하지도 못하는 직관에 의존한 (맞을꺼 같다라고 생각되는) 가설을 내세우고 수십년이나 지나 후대의 수학자들이 그것을 간신히 증명해내는것을 보면 사실 그 직관의 힘이 가볍게 보여지지는 않는다.

어찌되었든 수학이나 과학의 영역에 있는것이 아니다 하더라도 끊임없이 문제를 해결해야 하는 개발자에게 훈련을 통해 갖춰야할 주요한 능력임에는 틀림이 없어 보인다.

2016-10-18 오전 1:45:19

설정

트랙백

댓글

eshell에서 Java의 한글 인코딩 문제

Emacs 2016. 10. 17. 11:16

eshell에서 Java의 한글 인코딩 문제

문제

emacs의 eshell에서 java class를 컴파일 하고 실행했을때 한글이 깨져서 출력되는 인코딩 문제가 발생

import java.util.*; // Scanner를 사용하기 위해 추가

class ScannerEx {
    public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);

    System.out.print("두자리 정수를 하나 입력해주세요.>");
    String input = scanner.nextLine();
    int num = Integer.parseInt(input); // 입력받은 문자열을 숫자로 변환

    System.out.println("입력내용 :" + input);
    System.out.printf("num=%d%n", num);
    }
}
$ javac -encoding utf-8 ScannerEx.java
$ 
$ java ScannerEx
   ڸ          ϳ   Է    ּ   .>10
 Է³    :10
num=10
$ 

설명

emacs 편집기에서 기본 인코딩이 유니코드(utf-8)로 설정이 되어있다면 eshell에서도 그대로 그 설정을 따른다. 그러나 java는 기본적으로 운영체제의 기본 인코딩을 따르도록 되어있고 한글 윈도우의 기본 인코딩은 유니코드가 아닌 ms949이다. 즉, eshell의 인코딩은 유니코드 이지만 java 코드를 실행했을때 java는 외부 환경이 ms949 인코딩이라 판단하여 인코딩 충돌이 발생하는것이다.

문제 해결

java로 실행을 할때 -Dfile.encoding=utf-8 옵션으로 직접 인코딩을 지정해준다. (주의 : -D 와 file.encoding 사이에 공백이 없음)

$ java -Dfile.encoding=utf-8 ScannerEx
두자리 정수를 하나 입력해주세요.>10
입력내용 :10
num=10

매번 긴 옵션을 타이핑 하는것은 번고롭기 때문에 eshell에서 alias 설정(일종의 별명)을 해주자.

$ alias javac 'javac -encoding utf-8 $*'
$ alias java 'java -$*'
$
$ java ScannerEx
두자리 정수를 하나 입력해주세요.>100
입력내용 :100
num=100
$ 

alias 설정은 일회성이 아니고 별도의 파일인 ~/.emacs.d/eshell/alias 에 기록되어 필요에 따라 편집이 가능하다. 직접 alias를 수정할 경우 emacs 세션을 재 시작해야 적용되는것 같다.

2016-10-17 오전 11:13:28

설정

트랙백

댓글

자바 컴파일시 인코딩 문제

Java 2016. 10. 14. 18:40

자바 컴파일시 인코딩(encoding) 에러

문제가 발생하는 코드

class Hello {
    public static void main(String[] args) {
    System.out.println("Hello, world."); // 화면에 글자를 출력한다.
    }
}

컴파일 오류

컴파일 시 error: unmappable character for encoding MS949 오류가 발생.

 $ javac Hello.java
Hello.java:3: error: unmappable character for encoding MS949
    System.out.println("Hello, world."); // ?  면에   ??    ? 출력?  ?  .
                                            ^
Hello.java:3: error: unmappable character for encoding MS949
    System.out.println("Hello, world."); // ?  면에   ??    ? 출력?  ?  .
                                                   ^
Hello.java:3: error: unmappable character for encoding MS949
    System.out.println("Hello, world."); // ?  면에   ??    ? 출력?  ?  .
                                                    ^
Hello.java:3: error: unmappable character for encoding MS949
    System.out.println("Hello, world."); // ?  면에   ??    ? 출력?  ?  .
                                                       ^
Hello.java:3: error: unmappable character for encoding MS949
    System.out.println("Hello, world."); // ?  면에   ??    ? 출력?  ?  .
                                                            ^
Hello.java:3: error: unmappable character for encoding MS949
    System.out.println("Hello, world."); // ?  면에   ??    ? 출력?  ?  .
                                                              ^
6 errors

설명

교재의 간단한 첫 예문부터 오류가 발생해서 당황하긴 했는데, 오류 메세지에 나와있는대로 문자 인코딩의 문제로 컴파일을 거부하고 있는 모습이다. 오류가 난 지점을 ^ 문자로 표시하는데 그 부분의 문자열이 인코딩 문제로 깨져보이는것을 알 수 있다.

컴퓨터에서 한글 문자는 역사적인 이유로 각각의 문자를 비트열로 부호화하는 방식(인코딩)이 몇가지가 되는데, 대표적으로 많이 쓰이는것들이 utf-8, euc-kr, cp949, ms949 정도 있다.호환성을 위해 어느곳이나 유니코드(utf-8 등)를 사용하는것이 좋다라고 생각해서 utf-8 인코딩으로 코드를 작성하였다.

위 문제는 utf-8로 인코딩된 코드를 자바 컴파일에서 한글 윈도우의 기본 인코딩을 따라서 ms949 방식으로 읽으려고 시도했지만 실패하여 발생한것이다. utf-8과 ms949와 같은 다른 한글 인코딩은 1바이트로 표시되는 영문자를 포함한 ascii 문자에서만 서로 호환성을 가질 뿐이라서 영문자들은 잘 표시되지만 한글은 알수 없는 엉뚱한 문자로 해석될 뿐이다

해결 방법

해결 방법은 소스파일과 컴파일러의 인코딩 방식을 서로 일치 시켜주는 것으로 해결 할 수 있는데, 대략 아래 3가지 방법으로 생각해볼수 있겠다.

  1. 편집기에서 파일 인코딩을 ms949로 저장 하도록 하는 방법
  2. 통합개발환경에서 컴파일 옵션으로 -encoding utf-8 을 설정하는 방법
  3. 자바 컴파일러에게 명시적으로 파일의 인코딩을 지정하는 방법(javac 파일명 -encoding utf-8)

개인적으로는 2~3번 방법을 사용하여 utf-8 인코딩만을 사용하는것을 권한다. 그 이유는 유니코드가 산업 표준으로 대부분의 환경에서 지원하여 다국어 환경에서 인코딩이 달라 서로 호환되지 않는 문제가 없기 때문이다.

$ javac Hello.java -encoding utf-8
$

2016-10-14 오후 6:27:10

'Java' 카테고리의 다른 글

자바 연산자 우선순위(Operator Precedence)  (0) 2016.10.18

설정

트랙백

댓글