연산자 Operator
프로그래밍에서 연산자는 연산을 지시하는 부호를 뜻합니다. 피연산자는 연산의 대상으로 연산자의 양옆에 위치하게 됩니다.
예시 ) 4 + 5
4, 5 : 피연산자
+ : 연산자
연사자의 종류에 따른 분류
종류 | 연산자 |
부호 연산자 | + - |
증감 연산자 | ++ -- |
논리 부정 연산자 | ! |
비트 부정 연산자 | ~ |
산술 연산자 | + - * / % |
쉬프트 연산자 | << >> |
비교 연산자 | > < >= <= == != |
비트 연산자 | | & ^ |
논리 연산자 | && || |
조건 연산자 | ? : |
대입 연산자 | = |
연사자의 피연산자의 개수에 따른 분류
1개 → 단항 연산자 : 부호, 증감, 논리부정, 비트부정
2개 → 이항 연산자 : 산술, 쉬프트, 비교, 비트, 논리, 대입
3개 → 삼항 연산자 : 조건
부호 연산자 + -
- 수 앞에 붙는 - 와 +가 있습니다. 부호를 나타냅니다.
- boolean 타입과 char 타입을 제외한 나머지 기본 타입에 사용할 수 있습니다.
- 결괏값은 int 타입입니다.
증감 연산자 ++ --
- 전위형과 후위형이 있습니다. 변수 값을 1 증가시키거나 감소시킵니다.
- boolean 타입을 제외한 나머지 기본 타입에 사용할 수 있습니다.
- 결괏값은 증감 전 타입과 동일합니다.
- 증감 연산자가 하나의 식에서 너무 많이 사용되면 참조와 증감의 순서를 계산해 사용하는 것이 어렵기 때문에 식을 나누어 사용하는 것이 바람직합니다.
전위형 : 값이 참조되기 전에 증가시킵니다. ++i, 값이 참조되기 전에 감소시킵니다. --i
후위형 : 값이 참조된 후에 증가시킵니다. i++, 값이 참조된 후에 감소시킵니다. i--
논리 부정 연산자 !
- 논리값(true, false)을 반대로 바꿉니다.
- boolean 타입에만 사용할 수 있습니다.
- 결괏값 또한 boolean 타입입니다.
비트 부정 연산자 ~
- 이진수를 연산합니다.
- 0은 1로, 1은 0으로 바꿉니다.
- 부호 있는 타입의 피연산자는 부호가 반대로 변경됩니다.
- 결괏값은 int 타입입니다.
예시 ) 1010 -> 0101
산술 연산자 + - * / %
- 수를 연산합니다.
- 덧셈 + , 뺄셈 - , 곱셈 * , 나눗셈 /, 나머지 % 계산이 가능합니다.
- 덧셈 +의 경우 수의 산술 연산뿐만 아니라 문자나 문자열의 덧셈도 가능합니다. (사실 문자는 유니코드로 환산되기 때문에 수의 산술입니다.)
주의 사항
정수 나누기
int n1 = 5; int n2 = 3; System.out.println(n2 / n1); // 결과 : 1
정수끼리의 연산 결과는 소수점 아래 값을 버린 정수값으로 나옵니다.
문자 덧셈
char c1 = 'a'; // char c2 = c1 + 1; 컴파일 에러 발생 char c3 = 'a' + 1; System.out.pritnln(c3); // 결과 : b
‘a’ + 1은 리터럴 간의 연산으로 형변환 없이도 'b'로 계산되어 c3에 대입됩니다.
그러나 변수의 경우 컴파일러가 미리 계산을 할 수 없기 때문에 int형의 결괏값을 얻게 됩니다.
따라서 char형 결괏값을 얻기 위해서는 형변환((char)(c1 + 1))이 필요합니다.
문자열 덧셈
int n1 = 1; int n2 = 2; String n3 = "2"; System.out.println(n1 + n2); // 결과 : 3 System.out.println(n1 + n3); // 결과 : 12 System.out.println(n1 + n2 + n3); // 결과 : 32
문자열과 더해진 피연산자는 문자열로 형변환되어 계산됩니다. 그러나 연산은 순서대로 이루어지기 때문에 n1 + n2 + n3을 계산하게 되면 n1 + n2가 계산된 3에 n3의 값 "2"가 더해져 32가 됩니다.
결괏값이 자료형의 범위를 넘어간다면?
int a = 2147483647; int b = 2147483647; // Long c = a + b; a + b 의 결괏값은 int형이므로 에러발생 int c = a + b; // -2
a와 b는 모두 int형입니다. 일반적인 상식으로 생각했을 때 2,147,483,647 + 2,147,483,647는 4,294,967,294이기 때문에 int형이 아닌 Long형으로 선언하는 것이 맞는 것 같습니다. 하지만 이는 틀렸습니다. int형과 int형의 연산 결괏값은 Long형이 아닌 int형입니다.
그렇다면 c에는 어떤 값이 저장되는 걸까요? 답은 -2입니다. 이는 연산과정에서 오버플로우가 발생하기 때문입니다. int형의 최댓값인 2,147,483,647에 1을 더하게 되면 int형의 최솟값인 -2,147,483,648가 됩니다. 따라서 2,147,483,647에 2,147,483,647을 더했을 땐 -2라는 결괏값이 나오게 되는 것이죠.
쉬프트 연산자 << >>
- 이진수를 연산합니다.
- 결괏값은 int 타입입니다.
<< : 왼쪽 피연산자의 2진수의 각 자리를 왼쪽으로 이동시키며 빈칸을 0으로 채웁니다.
>> : 왼쪽 피연산자의 2진수의 각 자리를 오른쪽으로 이동시키며 왼쪽 피연산자가 음수인 경우 빈자리를 1로, 양수일 때는 0으로 채웁니다.
예시 )
8 << 2 // 결과 32
왼쪽 피연사자인 10진수 8의 2진수(1000)를 왼쪽으로 2자리 이동하고(1000XX)
빈자리는 0으로 채웁니다. (00000000 00000000 00000000 00100000)
-8 >>2 // 결과 -2
왼쪽 피연사자인 10진수 -8의 2진수(11111111 11111111 11111111 11111000)를
오른쪽으로 2자리 이동하고(XX111111 11111111 11111111 11111110)
왼쪽 피연사자가 음수이기 때문에 빈자리를 1로 채웁니다. (11111111 11111111 11111111 11111110)
⭐ 음수의 2진수 구하는 법 :
- 2진법의 음수표현은 2의 보수법을 이용합니다.
- 어떤 수의 ‘n의 보수’는 더했을 때 n이 되는 수를 말합니다. 그러므로 2의 보수는 더했을 때 2가 되는 수겠죠.
- 10진 음수를 2진수로 표현하려면 음수의 절댓값을 구해 2진수로 변환하고 이 수의 2의 보수를 구해주면 됩니다.
- 2의 보수 = 1의 보수 + 1입니다.
- 1의 보수를 구하는 방법은 0을 1로, 1을 0으로 변환하면 됩니다. 위에 설명드렸던 비트 부정 연산자(~)를 적용한 결괏값과 같겠죠. 이때 음수 기호를 나타내는 1이 앞에 붙는 형태여야 합니다.
- -50 → 50 → 0110010 → 1001101+1 → 1001110
❗ 8을 굳이 32글자로 표현한 이유는 뭔가요?
int 형이 32bit(4byte)의 크기를 갖기 때문입니다.
비교 연산자 > < >= <= == !=
- 대소비교연산자 : > < >= <= 크기를 비교하는 연산자입니다.
- boolean 타입을 제외한 나머지 기본 타입에 사용할 수 있습니다.
- 등가비교연산자 : ==(같다), != (같지 않다)
- 모든 타입에 사용할 수 있습니다.
- 기본형의 경우 저장되어 있는 값이 같은지를 알 수 있고,
- 참조형의 경우 객체의 주소값을 비교하기 때문에 두 개의 피연산자가 같은 객체를 가리키고 있는지를 알 수 있습니다.
- 두 비교 연산자의 결괏값은 모두 boolean 타입입니다. ( true / false )
- 문자열의 내용이 같은지 비교하기 위해서는 등가비교 연산자 대신 equals()를 사용합니다.
- 문자열의 내용이 같은지 비교할 때 대소문자를 구별하지 않고 비교하려면 equalsIgnoreCase()를 사용하면 됩니다.
비트 연산자 | & ^
x | y | x | y | x & y | x ^ y |
1 | 1 | 1 | 1 | 0 |
1 | 0 | 1 | 0 | 1 |
0 | 1 | 1 | 0 | 1 |
0 | 0 | 0 | 0 | 0 |
논리 연산자 || &&
x | y | x || y (OR) | x && y (AND) |
T | T | T | T |
T | F | T | F |
F | T | T | F |
F | F | F | F |
- 논리 연산자는 효율적인 연산을 합니다.
- x || y를 구할 때 x가 T이면 y값은 평가하지 않고 T의 결괏값을 냅니다.
- x && y를 구할 때 x가 F이면, y값은 평가하지 않고 F의 결괏값을 냅니다.
- 따라서 같은 조건식이라도 피연산자의 위치에 따라서 연산속도가 달라질 수 있습니다.
조건 연산자 ? :
피연산자가 3개 사용되는 삼항연산자입니다. 연산자만으로 조건문의 기능을 사용할 수 있어 아주 유용합니다.
result = (조건식)? 식 1 : 식 2
조건식이 참일 경우 식 1을, 거짓인 경우 식 2를 반환합니다.
대입 연산자 =
연산자의 오른쪽 값을 왼쪽 변수에 대입합니다.
복합 대입 연산자
복합 대입 연산자에는 두 개의 연산자가 붙어 있습니다. 이때 왼쪽 연산자로 먼저 연산한 값을 왼쪽 변수에 대입하는 연산자입니다.
+=, -=, *=, /=, %=, <<=, >>=, &=, ^=-, |=
연산자의 우선순위
대입 연산자 < 조건연산자 < 논리 연산자(OR < AND) < 비트 연산자 < 비교 연산자 < 쉬프트 연산자 < 산술 연산자(덧셈, 뺄셈 < 곱셈, 나눗셈) < 단항 연산자
오른쪽에 있는 연산자가 우선순위가 높습니다.
참고하기 좋은 사이트를 링크해 드리겠습니다.
연산자의 결합규칙 방향
단항 연산자 | ← |
산술 연산자 | → |
비교 연산자 | → |
논리 연산자 | → |
삼항 연산자 | → |
대입 연산자 | ← |
연산자에 대해 알아보았습니다. 잘 따라오고 계시겠죠? 다음에는 조건문과 반복문에 대해 알아봅시다. 조건문과 반복문은 프로그래밍의 핵심이라고 할 수 있습니다. 적절한 조건문과 반복문 없이는 좋은 프로그램을 만들 수 없습니다. 코딩테스트에서도 얼마나 효율적인 조건문과 반복문을 작성했는지 확인합니다. 그럼, 핵심을 다루기 위해 다음 글에서 찾아뵙도록 하겠습니다.
'개발언어 > Java : 자바' 카테고리의 다른 글
자바 쉽게 배우기 6 - 클래스와 객체 (0) | 2023.01.06 |
---|---|
자바 쉽게 배우기 5 - 배열 (0) | 2023.01.04 |
자바 쉽게 배우기 4 - 조건문과 반복문 (0) | 2023.01.03 |
자바 쉽게 배우기 2 - 변수 (0) | 2023.01.01 |
자바 쉽게 배우기 1 - 자바란 무엇인가? (0) | 2022.12.30 |