•
산술 연산자
•
비트 연산자
•
관계 연산자
•
논리 연산자
•
대입 연산자(Assignment Operators)
•
연산자 우선 순위
•
3항연산자
•
화살표(→) 연산자
•
java 13 switch 연산자
산술연산자?
단순하다. +, -, /, *, %의 연산자들을 산술연산자라 부른다. 사용법도 간단하다.
int c = a + b;
int c = a - b;
int c = a / b;
int c = a * b;
단, 규칙이 있다.
1. 0으로 나누면 안된다(무한대가 나온다).
2. 연산을 통하여 할당할 자료형의 범위를 넘어서는 데이터를 넣으려고하면 오버플로우가 발생한다.
비트연산자?
비트?라고 하면 전공자가 아니면 조금 익숙하지 않을 거다. 그래서 조금 설명하면 컴퓨터는 모든 정보를 메모리에 이진수형태로 저장된다. 하나의 Bit는 true/false, 1/0 처럼 2가지 상태만 표현할 수 있다. 즉, Bit라 하면 2가지의 상태를 나타내는 것이다. 그런데 중요한 것은 이러한 Bit들의 집합을 만들어 컴퓨터는 처리한다. int의 경우는 2^32로 총 가지 4,294,967,296 가지를 표현할 수 있다. 이걸 2로 나누면 2,147,483,648가지로 int형 자료의 범위 값이 된다. 물론 음수 양수 표현 때문에 2로 나눈거다. 그럼 간단해진다. 이러한 비트를 이용하여 연산을 하는 것이 비트 연산자다.
변환 방법
비트연산자의 종류에는 &, |, ^, ~, <<, >>, >>> 차례대로 풀어보면
& : and와 같고 비트를 연산하여 같으면 1이 나온다.
| : or와 같고 비트를 연산하여 둘중하나라도 1이 존재하면 1을 리턴한다.
^ : xor 연산으로 상호간의 관계가 다를때 1을 리턴한다.
~ : not 연산으로 1을 0으로 0을 1로 바꿔 준다.
>>, <<: 오른쪽으로 라고 생각하면 편하다. 그래서 규칙이 하나 존재한다. 왼쪽으로 밀때는 2^n, 오른쪽으로 밀때는 2^n을 나누면 간단하다. 정말 신기한 것은 음수가 유지된다.
>>>, <<<: 이친구는 Unsigned 연산자다. 같은 쉬프트 연산이지만 부호를 신경안쓰고 민다.
//특이점
public class Main {
public static void main(String[] args) {
// 미리 필자가 변환
// 원리
// 양수 2의 2진법 표현 00000010 하지만 int의 경우 32비트 표현 그래서 0을 앞에 붙여준거
// 보수를 구함 11111101 + 1을 해줌 -> 11111110 그로면 -2가 표현됨 앞에는 전부 1붙여줌
int 양 = 0b00000000000000000000000000000010; //2
int 음 = 0b11111111111111111111111111111110; //-2
System.out.println(양); // 2
System.out.println(음); // -2
System.out.println(Integer.toBinaryString(음 & 0XFF)); // 11111110
System.out.println(Integer.toBinaryString(~양 & 0XFF)); // 11111101
System.out.println(~양); // -3 이렇게 나오는 이유는 '~'연산은 단순 0 -> 1, 1 -> 0으로만 변환
// 그런데 왜 부호가 붙나?
// 그 이유는 맨 앞자리 비트는 부호 용이다. 그래서 0 = 양수, 1 = 음수를 표현
System.out.println(Integer.toBinaryString(양 & 0XFF)); // 10
System.out.println(Integer.toBinaryString(~음 & 0XFF)); //1
System.out.println(~음); // 1
}
}
일반적으로 10을 2진수로 표현하면 8Bit 기준으로 00000010이 된다. 그럼 not 연산을 한다면
11111101(253)이 된다. 하지만 실제로 ~10한다면 111111111111111111111111 11110101이 나오고
결과 10진수 값은 -11이 된다. 이것의 원리는 양의 정수에서는 음수로 변환이 될때 1의 보수를 구한이후
1을 더해주기 때문이다. 그래서 실제로 변환한것과 콘솔에 찍어보는것이 다르게 출력되는 수 자체는 다르게
보이는 것이다.
CONSOLE RESULT
2
-2
11111110
11111101
-3
10
1
1
Java
복사
관계연산자?
나보다는 여기 블로그가 더 잘 정리한 것 같다. 나도 이걸보고 당연히 맞다고 생각되어 이 블로그를 남긴다.
논리연산자?
나보다는 여기 블로그가 더 잘 정리한 것 같다. 나도 이걸보고 당연히 맞다고 생각되어 이 블로그를 남긴다. 하지만 여기서 정말 좋았던 내용은 JVM에 부담이 덜 주는 연산 법이 좋았다.
And연산에서 첫번째 조건에 False 조건을 맞춘다거나, 아니면 배열의 길이를 검사할때 NPE발생이 되냐, 안되냐가 너무 좋았다. 예를 들자면 배열이 null 이 아니어야 하는 상황은 존재한다. 하지만 단순 &&, || 조건을 맞추면 둘다를 검사하지 못할 수 있다. 하지만 &, | 은 모두 연산을 진행하고 그 이후에 논리연산을 실행한다. 이건 정말 좋은 내용이다.
대입연산자?
나보다는 여기 블로그가 더 잘 정리한 것 같다. 나도 이걸보고 당연히 맞다고 생각되어 이 블로그를 남긴다. 모두 똑같은 내용 같아서 좀 그렇긴하다. 그래도 잘 정리해서 좋다.
일단 다른 건 다 보기 좋은 내용이고 증감 연산자에 전위 ++, 후위 ++의 차이를 잘 설명해주었다.
”‘++ 변수’ 는 값이 참조되기 전에 증가하고, ‘변수 ++’ 는 값이 참조 된 후에 증가하게 된다.”
3항연산자?
나보다는 여기 블로그가 더 잘 정리한 것 같다. 나도 이걸보고 당연히 맞다고 생각되어 이 블로그를 남긴다. 하지만 이런 의문도 들었다. 좋으면 if 문이 없어져야 하는 것이 아닌가? 하지만 있다. 그건 이유가 있겠지?
3항의 다른 면
: 출처
이렇게 쓰면 아주 곤란해진다. 누가 와도 읽기 싫어지는 코드이다. 그런데 재미있는 사실은 3항 연산자는 잘못이 없다. 그럼 이런 코드는 잘못된 코드지만 잘 된 코드는 무엇일까?
: 출처
: 출처
위의 코드를 삼행으로 변경했다. 매우매우 심플한 코드가 되었다. 그래서 나름 여기서 조언을 얻어 나만의 결론을 내려봤다.
나만의 결론
두 가지 이상의 조건문의 결합이 이루어질 때는 if 문을 쓰자, 하지만 두 가지 이상의 조건문을 isXXX() 처럼 만들 수 있다면 위의 마지막 그림처럼 만드는 것이 좋은 방법이다. 즉, 조건문을 한 word 로 표현 할 수 있을땐 3항연산자는 누구보다 좋은 연산자가 될 것 같다. 필자의 견해지 무조건 적으로 맞는 건 아니다. 단지 이런 방법도 존재한다는 것을 알았다. 아래와 같은 스타일로 사용하면 뭐가 좋을까? 일단 if분기 내부에서 값을 할당 또는 리턴할 때 변수명을 신경안써도 된다. 3항 하나의 리턴에서 이루어 지기 때문에 가능하다. 반환 값에 대하여 신경을 온전히 쏟을 수 있기 대문에 좋다. 이렇게 쓰고 나니 생각보다 읽기 편하다.
물론 JS 코드를 보고 영감을 얻은 방법이라 다를 수 있다. 하지만 적용할만한 가치가 충분한 것 같다. 예전에 신호 대비 잡음이 적다라는 말을 모던 자바의 람다를 공부하면서 들은 기억이 있다. 이 3항연산자도 충분히 그런 잡음비가 적은 것 같아 보기 좋다.
public class Main {
public static void main(String[] args) {
/*
+, -, /, * 연산을 반환해야한다면?
단, 단순 String으로 반환
input 값은 동일하게 char가 들어옴
*/
char in = '/';
if (in=='+'){
System.out.println("+");
} else if (in=='-') {
System.out.println("-");
}else if (in=='/') {
System.out.println("/");
}else if (in=='*') {
System.out.println("*");
}
}
}
-> 읽기 어려운 3항연산 스타일
String oper = in=='+' ? "+" : in == '-' ? "-" : in == '/' ? "/" : in =='*' ? "*" : "";
System.out.println(oper);
-> 읽기 편한 3항연산 스타일
String oper = isAdd(in) ? "+" :
isMinus(in) ? "-" :
isDiv(in) ? "/" :
isMult(in) ? "*" : "";
System.out.println(oper);
Java
복사
연산자 우선순위?
이분은 뭐 하는 분일까..
화살표(→)연산자?
이전에 모던 자바 인 액션을 공부하면서 진짜 어려웠다… 하지만 그 고통을 끝내고 몸(?)으로 기억하게 되었다. 아래는 내가 예전에 공부했던 내용이다.
java13의 switch?
java12 부터 switch연산자가 추가 되었다. 기존에는 불필요할 정도로 잡음이 심했다. 그리고 Error발생시 디버깅이 어려웠다. 하지만 12부터는 화살표 연산자를 사용할 수 있고 12부터는 switch를 사용할 때 바로 리턴을 통하여 대입이 가능해졌다. 13이후로는 yield가 추가되어 변수에 값을 바로 넣을 수 있게 되었다.