연산자 우선순위
연산자란 어떤 대상체에 대해 계산을 수행하도록 하는 특수한 문자 기호의 총칭이다.
그래서 어떤 연산자가 먼저 실행하는지, 그 연산자가 어떠한 일을 하는지 알아야 한다.
일반적인 실행순서는 왼쪽에서 오른쪽, 위에서 아래이지만, 예외적인 상황 중 하나가
연산자가 사용되었을 때 이다.
boolean bool = 4 + 5 > 2 - 1 * 7 && (12 & 3 * 2) > 7 || -2 != 2;
결과는 true의 값이 저장된다.
이유는??
우선 ()안을 먼저 계산 하는데 & 와 * 중 * 를 먼저 계산해야 하므로
(12&6) 00001100 & 00000110 = 00000100 이므로 닶은 4
4+5>2-1*7&&4>7||-2!=2;
산술연산을 해준다. *와 /가 +나 -보다 우선순위가 높으므로
9>-5&&4>7||-2!=2;
관계연산자를 계산해 준다.
9>-5 true, 4>7 false, -2!=2 true 따라서
true && false || true;
false || true;
true;
연산자의 우선순위는 다음과 같다.
최우선연산자 > 단항연산자 > 산술연산자 > 쉬프트연산자 > 관계연산자 > 비트연산자
> 논리연산자 > 삼항연산자 > 배정대입연산자 > 증감후위연산자 > 순차연산자
최우선연산자 - “.”, “[]”, “()”
. : 참조연산자 - 클래스의 멤버를 사용하기위해 사용됨
[] : 배열참조연산자? - 배열위 위치번째를 나타낼때 사용됨
() : 괄호연산자 - 특정연산자를 묶어 먼저 처리할수 있게 만들어 주는 연산자
public class Exec_01 {
public static void main(String[] args) {
System.out.println("Test");
int x = 5 + 3 * 2;
int y = (5 + 3) * 2;
System.out.println("x = " + x);
System.out.println("y = " + y);
}
}
단항연산자 - "!" , "~" , "+/-" , "++/--" , "(cast 자료형)" , "instanceof"
! : 논리부정 - 내용의 반대되는 값을 표현, boolean자료형에서만 사용가능
public class Exec_02 {
public static void main(String[] ar) {
boolean bool = false;
System.out.println("a = " + bool);
System.out.println("b = " + !bool);
boolean bool1 = 5 > 3;
System.out.println("c = " + bool1);
System.out.println("d = " + !(5 > 3));
//System.out.println("e = " + !5);
}
}
~ : 비트부정 - 비트단위로 부정을 한후, 2진수 0은 1로, 1은 0으로 바꾸는 작업
boolean, 실수형자료형에서는 사용 불가
byte,short,char,int 형은 ~연산후 int형이나 long형에 결과값을 담을수 있고
long형은 ~연산후 long형에만 담을수 있다.
public class Exec_03 {
public static void main(String[] args) {
System.out.println("a = " + ~(~(4)));
int x = +4;
int y = -4;
int z = -4 * -3;
System.out.println("z = " + z);
}
}
+/- : 부호연산자
++/-- : 특정필드의 값을 하나 증감시키는 연산자
앞쪽에 적히는 경우가 우선순위 2순위인 단항연산이고
뒤에 붙으면 우선순위 11위인인 증감 연산 후위형에 속한다.
int a=5; int k = 4 + ++a * 3; k=22, a=6(연산전 계산)
int a=5l int k = 4 + a++ * 3; k=19, a=6(연산후 계산)
public class Exec_04 {
public static void main(String[] args) {
int x = 10;
int y = ++x;
System.out.println("x = " + x);
System.out.println("y = " + y);
}
}
public class Exec_05 {
public static void main(String[] ar) {
int x = 10;
int y = x++;
System.out.println("x = " + x);
System.out.println("y = " + y);
}
}
(cast 자료형) - ex : int i = 1; byte by = (int) i; 단항연산자라고 알아두자
instanceof
객체의 타입을 비교 하는 연산자로서 우변의 객체와 좌변의 객체의 타입을 비교
우변과 좌변의 객체의 타입이 서로 같다면 true 그렇지 않다면 false를 반환
public class Exec_06 {
public static void main(String[] args) {
Exec_06 ex = new Exec_06();
boolean bool = ex instanceof Object;
System.out.println("bool = " + bool);
}
}
산술연산자 - +, -, *, /, %
byte, short, char, int형의 자료형의 연산은 int 형의 자료형으로 나타나며
long, float, double형의 자료형은 큰 자료형의 결과로 나타난다
(long<float<double)
float형과 double형의 연산은 혼용하여 사용하지 않는것이 좋다.
public class Exec_07 {
public static void main(String[] args) {
float f = 1.2f;
double d = 1.2;
double d1 = d - f;
System.out.println(d1);
}
}
나눗셈과 나머지 구하는 문제
public class Exec_08 {
public static void main(String[] args) {
int x = 10;
int y = 3;
System.out.println("몫 = " + x / y);
System.out.println("나머지 = " + x % y);
}
}
시프트연산자“<<“ ,“>>”,“>>>”
- 자바프로그램에서 사용하는 기본 메모리는 32비트인데,
때때로 메모리 절약을 위해 int형 하나의 데이터에 16비트씩 2개의
데이터를 함께 사용하는 경우나, 8비트씩 4개의 데이터를 함께
사용하는 경우, 필요한 데이터의 결과값만 꺼내려구 할때 사용
대상필드의 값을 2진비트로 바꾼 후 특정 비트 수 만큼 이동시켜 원하는
부분의 비트데이터를 얻어내는 연산자
boolean형, float형, double형에서는 사용할수 없다
a<<b : left shift 연산자
a의 값을 2진비트로 바꾼후 왼쪽으로 b비트수만큼 이동시키고 빈자리는
0으로 채우는 연산자
예) 2<<3
2을 32비트로 분해한다음 왼쪽으로 3bit 이동시켜라
0000 0000 0000 0000 0000 0000 0000 0010
000 0000 0000 0000 0000 0000 0000 0001 0???
앞의 000 은 버리고 뒤의 ???는 000 으로 채운다
결과는
0000 0000 0000 0000 0000 0000 0001 0000 이 된다
적용 공식 : 원본데이타 *2^이동변수
a>>b : right shift 연산자
a의 값을 2진비트로 바꾼후 오른쪽으로 b비트수만큼 이동시키고 빈자리는
원본 데이타의 값이 양수이면 0을, 음수이면 1을 채우는 연산자
적용 공식 : 원본데이타 / 2^이동변수
“>>>”unsigned right shift 연산자
>> 연산자와 기본원리는 똑같으나, 원본데이타가 음수일 경우에도 앞의 빈
비트를 0으로 채운다는 사실이 다르다. 자바에만 있는 기술이다.
원본데이터에 관계없이 결과는 무조건 양수로만 나타나게 된다.
-8>>3
1111 1111 1111 1111 1111 1111 1111 1000
???1 1111 1111 1111 1111 1111 1111 1111
여기서 원본데이터가 양수이면 0을 음수이면 1을 채운다
1111 1111 1111 1111 1111 1111 1111 1111
결과는 -1이된다.
-8>>>3
1111 1111 1111 1111 1111 1111 1111 1000
???1 1111 1111 1111 1111 1111 1111 1111
원본데이터에 상관없이 무조건 0을 채운다
0001 1111 1111 1111 1111 1111 1111 1111
결과는 536870911
public class Exec_09 {
public static void main(String[] args) {
int i = 1 << 3;
int j = 8 >> 3;
int k = -8 >> 3;
int l = -8 >>> 3;
System.out.println(" 1 << 3 = " + i);
System.out.println(" 8 >> 3 = " + j);
System.out.println("-8 >> 3 = " + k);
System.out.println("-8>>> 3 = " + l);
}
}
관계연산자
비교관계 : “>”, “<“, “>=“, “<=“
항등관계 : “==“, “!=“
비교관계연산자는 다 아는 경우이고,
항등관계 연산자는 피 연산자들이 서로 같은지 다른지를 판단하는 것
== 는 비교하는 두개의 피연산자가 같은면 true, 틀리면 false
!= 는 비교하는 두개의 피연산자가 같으면 false, 틀리면 true 반환
- !=는 관계연산자 이지만, =!는 뒤의 연산자를 부정한후 대입하라는 뜻
public class Exec_10 {
public static void main(String[] args) {
boolean bool = 5 < 3; // false
boolean bool1 = 10 != 10; // false
System.out.println("bool = " + bool);
System.out.println("bool1 = " + bool1);
boolean a = bool != bool1;
boolean b = bool =! bool1;
System.out.println("a = " + a);
System.out.println("b = " + b);
}
}
비트연산자 - “&”, “|”, “^”
& - and연산자, 대조되는 비트가 모두 1일때 결과값을 1로 주는 연산자
| - or연산자, 대조되는 비트 한쪽이라도 1이면 결과값은 1로주는 연산자
^ - exclusive or연산자, 대조되는 비트가 틀리면 1을 주는 연산자
public class Exec_11 {
public static void main(String[] ar) {
int a = 4;
int b = 7;
System.out.println("& = " + (a & b));//0100 & 1100 = 0100
System.out.println("| = " + (a | b));//0100 | 1100 = 1100
System.out.println("^ = " + (a ^ b));//0100 ^ 1100 = 0011
}
}
논리연산자 - “&&”,“||”
“&&”- and연산자, 피연산자를 비교하여 둘다 참이면 true 아니면 false
“||”- or연산자, 피연산자를 비교하여 둘중 하나만 참이면 ture, 아니면 false
public class Exec_12 {
public static void main(String[] ar) {
boolean bool = 5 < 3 && 7 > 4; /* false
false && true */
boolean bool1 = 10 != 11 || 7 <= 3; /* true
true || false */
System.out.println("bool = " + bool);
System.out.println("bool1 = " + bool1); // 여기까지 한번 보여주고
//아래의 경우도 한번 생각해 보자
int i = 1;
int j = 3;
boolean bool2 = ++i > j && i < ++j;
System.out.println("i = "+i);
System.out.println("j = "+j);
System.out.println("bool2 = "+bool2);
/* j의 값은 변화되지 않았다.
&&나||연산자는 앞쪽의 피연산자만으로 전체 상황판단이 가능하면
뒤쪽 피연산자는 실행 자체가 되지 않도록 되어 있다 */
i = 1;j = 3;
boolean bool3 = ++i > j & i < ++j;
System.out.println("i = "+i);
System.out.println("j = "+j);
System.out.println("bool3 = "+bool3);
/* 이렇게 &나 |으로 연산을 하면 뒤쪽 연산자도 실행이 되는 것을
알수있다 */
}
}
-- 결과값
bool = false
bool1 = true
i = 2
j = 3
bool2 = false
i = 2
j = 4
bool3 = false
삼항연산자 :“조건항 ? 항1 : 항2”
조건항이 참이면 항1번을 시행하고 조건항이 거짓이면 항2번을 실행한다
import java.io.*;
public class Exec_13 {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader
(new InputStreamReader(System.in));
System.out.print("1.남성 2.여성 = ");
int x = Integer.parseInt(in.readLine());
String str = x == 1 ? "남성" : "여성";
System.out.println("str = " + str);
}
}
삼항연산자에서 범하기 쉬운 오류(특히 c언어 배우신분들)
int a = 10;
a == 10 ? System.out.println("같다!") : System.out.println("다르다!");
=> not a statement 성립되지 않는 문장입니다.
int a = 10;
System.out.println(a == 10 ? "같다!" : "다르다!"); 로 고쳐줘야 한다.
String str = ""; int a = 0;
a != 0 ? str = "남성" : str = "여성";
=> unexpected type ... 오류가 발생한다.
String str = ""; int a = 0;
str = a != 0 ? "남성" : "여성";
자바는 문장의 형식을 중시한다.
배정대입연산자 : =, *=, /=, %=, +=, -=, <<=, >>=, >>>=
= : 대입연산자, 단순히 오른쪽에 있는 값을 왼쪽으로 옮겨라.
byte a = 5;
배정연산자
a = a - 5; 라고 하면 5값은 int형이라 오류가 발생한다.(형변환을 해줘야 함)
이렇때 형변환을 쓰지 않으면서 결과값은 같게 나오게 하는 해결책
우선적으로 배정되어 있는 다른 연산이 먼저 발생한 후에 대입연산을 해라
ex) a += b => a = a + b;
ex) a -= b => a = a - b;
ex) a *= b => a = a * b;
ex) a /= b => a = a / b;
ex) a %= b => a = a % b;
ex) a <<= b => a = a << b;
ex) a >>= b => a = a >> b;
ex) a >>>= b => a = a >>> b;
byte a = 5;
a = a - 5; 라고 하면 5값은 int형이라 오류가 발생한다.(형변환을 해줘야 함)
이렇때 형변환을 쓰지 않으면서 결과값은 같게 나오게 하는 해결책이다.
public class Exec_14 {
public static void main(String[] args) {
byte b = 10, a = 20;
//b = b + 1; <= 오류발생
b += 1; // b++; ++b;와 같은 경우
byte c = 12;
byte d = 50;
//c = c + d; 역시 오류가 발생
c += d;
System.out.println("c = " + c);
}
}
RECENT COMMENT