1 연산자
1.1 연산자
연산자는 프로그래밍 언어에 있어 가장 기본적이면서 도 중요하다.
각 연산자의 특징과 수행결과 그리고 우선순위에 대 해 파악해야 한다.
종류
연산방향
연산자
우선순위
단항연산자
-->
++ -- + - ! (타입)
높음
산술연산자
-->
* / %
-->
+ -
-->
<< >> >>>
비교연산자
-->
< > <= >= instanceof
-->
== !=
논리연산자
-->
& ^ | && ||
삼항연산자
-->
? :
대입연산자
<--
= *= /= %= += -= <<= >>= >>>= &= ^= !=
낮음
1.2 연산의 우선순위
앞장의 표에서 같은 줄에 있는 연산자들은 우선순위 가 같다.
우선순위가 같은 연산자들 간에는 연산의 진행방향에 의해 순서가 정해진다.
예를 들어,
3*4*5의 경우 : 오른쪽(->)으로 진행
3*4가 먼저 수행되고, 그 결과 값이 다시 5와 연산을 하게 된다.
x=y=3의 경우 : 왼쪽(<-)으로 진행
y에 3이 할당되고 다시 x에는 y의 값 즉, 3이 할당되는 순서로 연산이 진행된다.
2 단항연산자
2.1 증감연산자(++, --)
일반적으로 단항연산자는 피연산자의 왼쪽에 위치하 나, 증감연산자는양쪽모두가능하다.
기존
int age = age+ 1;
개선
int age = ++age;
연산자
특징
예
비고
++
선증가
int i = 6; int j = ++i;
i는7, j 도7
후증가
int i = 6; int j = i++;
i는7, j 는6
i값이증가되기전의값 이 할당됨
--
선감소
int i = 6; int j = --i;
i는5, j 도5
후감소
int i = 6; int j = i--;
i는5, j 는6
i값이감소되기전의값 이 할당됨
2.1 증감연산자(++, --)
주의
byte b = 0; b = b++;과 byte b = 0; b = b+1;은 엄연히 다르다!
why?
b++의 경우 byte형인 변수 b의 타입이 변경되지 않음
그러나 b+1의 경우 b의 타입이 int형으로 형변환되어 연산이 되 므로
이미 int형으로 변환된 변수 b를 다시 byte type에 할당이 안됨!
2.1 증감연산자(++, --)
예
int count=15;
int a, b, c, d;
a = count++;
b = count;
c = ++count;
d = count;
System.out.println(a+ “, “ + b + “, “ + c + “, “ + d);
결과
15, 16, 17, 17
2.2 부호연산자
-, +
부호연산자는 피연산자의 부호를 변경하는 데에 사용된다.
boolean과 char형을 제외한 나머지 기본형에 사용이 가능 하다.
+는 피연산자에 양수 1을 곱한 결과를,
-는 피연산자에 음수 1을 곱한 결과를 얻는다.
2.2 부호연산자
예제
class OperatorSimple{
public static void main(String[] args){
i=-10;
i = -i;
System.out.println(i);
}
}
결과
10
2.3 비트전환 연산자
~
정수형과 char형에서만 사용가능
피연산자를 0, 1 즉 2진수로 표시했을때 0을 1로 1을 0 으로 전환
주의 할 점은 연산시에,
byte, short, char의 경우 int로 변환(casting)된 후에 연산된다.
예
2진수
10진수
00001010
10
11110101
-11
2.4 논리부정연산자
!
오로지 boolean형에만 사용이 가능하다.
true는 false로 false는 true로 전환하여 준다.
2.4 논리부정연산자
예제
class OperatorEx7 {
public static void main(String[] args) {
boolean power = false;
System.out.println(power);
power = !power; // power의값이false에서true로바뀐다.
System.out.println(power);
power = !power; // power의값이true에서false로바뀐다.
System.out.println(power);
}
}
결과
false
true
false
3 산술연산자
3.1 종류
사칙연산자
+, -, *, /
나머지연산자
%
쉬프트연산자
<<, >>, >>>
3.2 특징
모두 두 개의 피연산자를 취하는 이항연산자임.
역시 이항연산자도 피연산자의 데이터형이 4byte보다 작은 경우 4byte형(즉, int형)으로 변환된 다음에 연산 을 수행한다.
3.3 사칙연산자
+, -, *, /
가장 많이 사용된다.
이미 알고 있듯이 곱셈(*), 나눗셈(/)이 덧셈(+), 뺄셈(-)연 산자 보다 우선순위가 높다.
특징
int형보다 크기가 작은 자료형은 int형으로 변환된 다음에 연산 이 수행된다.
두개의 피연산자중 자료형이 큰쪽에 맞춰서 형변환 된 후 연산이 수행된다.
정수형간의 나눗셈시 0으로 나누는 것은 금지되어 있다.
3.3 사칙연산자
예제
class OperatorEx8 {
public static void main(String[] args){
byte a = 10;
byte b = 20;
byte c = a + b; // compile error! a + b의결과값은int이다.
// byte c = (byte)(a+b); // 맞는표현
System.out.println(c);
}
}
3.3 사칙연산자
예제
class OperatorEx9{
public static void main(String[] args){
byte a = 10, b = 30;
byte c = (byte)(a* b);
System.out.println(c);
}
}
결과
44
원래는 300이 나와야 정상이지만 byte형의 범위를 넘어선 값인 300이 들어왔기 때문에 값의 소실이 있 었다.
3.3 사칙연산자
예제
class OperatorEx10{
public static void main(String[] args){
int a = 1000000;// 1,000,000 1백만
int b = 2000000;// 2,000,000 2백만
long c = a * b;// 2,000,000,000,000 2조
System.out.println(c);
}
}
결과
-1454759936
3.3 사칙연산자
결과
이유
a*b의 결과 값을 담는 c의 타입이 long이기 때문에 결과 값 인 2000000000000을 담아낼 수 있다고 생각 할 수 있다.
그러나 a*b 두 연산자 각각 int형이기 때문에 그 결과 값도 int형이며 그 결과값은 이미 int형의 memory에 저장이 된다.
따라서 그 후에 long type인 c에 할당 되더라도 값은 이미 예상되는 값인 2조가 아닌 다른 값이 저장되는 것이다.
2조의 값을 정확하게 얻고 싶다면 a나 b중 하나를 long type으로 선언해야 한다.
3.3 사칙연산자
예제
class OperatorEx11{
public static void main(String[] args){
long a = 1000000 * 1000000;
long b = 1000000 * 1000000L; // long형리터럴
System.out.println(a);
System.out.println(b);
}
}
결과
-727379968
1000000000000
3.3 사칙연산자
예제
class OperatorEx12{
public static void main(String[] args){
int a = 1000000 * 100000 / 1000000;
int b = 1000000 / 100000 * 1000000;
System.out.println(a);
System.out.println(b);
}
}
결과
-727
1000000
3.3 사칙연산자
결과
이유
어찌 보면 같은 결과가 나와야 함에도 두 연산의 결과는 다르 다.
이는 자료형의 표현범위의 제한 때문에 나타나는 결과이다.
첫번째 연산의 경우 먼저 곱하기가 이루어졌을 때 표현범위가 int형을 넘어서기 때문에 예상과는 다른 결과가 나온 것이다.
즉, 두번째는 나누기의 결과값이 1이고 이에 1000000을 곱 했기 때문에 int형의 표현 범위를 넘어서지 않아 정상적이고 예 상했던 결과가 나왔다.
3.3 사칙연산자
나눗셈에 대해
int와 int를 나누었을때
그 결과값의 자료형은 double이나 float가 아닌 int형임에 주 의해야 한다!
즉, 3/2의 결과는 1.5가 아닌 1이다.
3.4 나머지연산자
%
왼쪽의 피연산자를 오른쪽 피연산자로 나눈 나머지를 돌려 준다.
예제
class OperatorEx18{
public static void main(String[] args){
int share = 10 / 8;
int remain = 10 % 8;
System.out.println("10을8로나누면, ");
System.out.println("몫은"+share+"이고, 나머지는"+remain+"입니다.");
}
}
결과
10을 8로 나누면
몫은 1이고 나머지는 2입니다.
3.5 쉬프트연산자
<<, >>, >>>
정수형 변수에만 사용한다.
피 연산자의 각 자리를 표시된 수 만큼 표시된 방향으로 이동
x << n은 x*2n의 결과와 같다.
x >> n은 x/2n의 결과와 같다.
>>, <<의 경우 피연산자의 부호에 맞추어 변환을 하지만,
>>>의 경우 왼쪽을 무조건 0으로 채우기 때문에 뜻하지 않은 결과도 초래한다.
다만 숫자 n의 값이 자료형의 bit수 보다 크면 자료형의 bit수를 나눈 나머지 만큼 이동한다.
예를 들어 int a = 1000; a << 35;의 경우 int는 bit수가 32이 므로
35%32 = 3 즉, a << 3;과 같은 효과를 가진다.
3.5 쉬프트연산자
쉬프트연산자의 예
수식
자리이동
이진수
십진수
8 >> 0
없슴
00000000 00000000 00000000 00001000
8
8 >> 1
오른쪽으로 한번
00000000 00000000 00000000 00000100
4
8 >> 2
오른쪽으로 두번
00000000 00000000 00000000 00000010
2
-8 >> 0
없슴
11111111 11111111 11111111 11111000
-8
-8 >> 1
오른쪽으로 한번
11111111 11111111 11111111 11111100
-4
-8 >> 2
오른쪽으로 두번
11111111 11111111 11111111 11111110
-2
수식
자리이동
이진수
십진수
8 << 0
없슴
00000000 00000000 00000000 00001000
8
8 << 1
왼쪽으로 한번
00000000 00000000 00000000 00010000
16
8 << 2
왼쪽으로 두번
00000000 00000000 00000000 00100000
32
-8 << 0
없슴
11111111 11111111 11111111 11111000
-8
-8 << 1
왼쪽으로 한번
11111111 11111111 11111111 11111100
-16
-8 << 2
왼쪽으로 두번
11111111 11111111 11111111 11111110
-32
수식
자리이동
이진수
십진수
8 >>> 0
없슴
00000000 00000000 00000000 00001000
8
8 >>> 1
오른쪽으로 한번
00000000 00000000 00000000 00000100
4
8 >>> 2
오른쪽으로 두번
00000000 00000000 00000000 00000010
2
-8 >>> 0
없슴
11111111 11111111 11111111 11111000
-8
-8 >>> 1
오른쪽으로 한번
01111111 11111111 11111111 11111100
2147483644
-8 >>> 2
오른쪽으로 두번
00111111 11111111 11111111 11111110
1073741822
3.5 쉬프트연산자
class OperatorEx21 {
public static void main(Stringargs[]) {
int temp; // 계산결과를담기위한변수
System.out.println(-8);
System.out.println(Integer.toBinaryString(-8));// -8을2진수문자열로변경한다.
temp = -8 << 1;
System.out.println("-8 << 1 = " + temp + “ : “ + Integer.toBinaryString(temp));
temp = -8 << 2;
System.out.println("-8 << 2 = " + temp + “ : “ + Integer.toBinaryString(temp));
System.out.println(-8);
System.out.println(Integer.toBinaryString(-8));
temp = -8 >> 1;
System.out.println("-8 >> 1 = " + temp + “ : “ + Integer.toBinaryString(temp));
temp = -8 >> 2;
System.out.println("-8 >> 2 = " + temp + “ : “ + Integer.toBinaryString(temp));
System.out.println(-8);
System.out.println(Integer.toBinaryString(-8));
temp = -8 >>> 1;
System.out.println("-8 >>> 1 = " + temp + “ : “ + Integer.toBinaryString(temp));
temp = -8 >>> 2;
System.out.println("-8 >>> 2 = " + temp + “ : “ + Integer.toBinaryString(temp));
}
}
3.5 쉬프트연산자
결과
-8
11111111111111111111111111111000
-8 << 1 = -16 : 11111111111111111111111111110000
-8 << 2 = -32 : 11111111111111111111111111100000
-8
11111111111111111111111111111000
-8 >> 1 = -4 : 11111111111111111111111111111100
-8 >> 2 = -2 : 11111111111111111111111111111110
-8
11111111111111111111111111111000
-8 >>> 1 = 2147483644 : 1111111111111111111111111111100
-8 >>> 2 = 1073741822 : 111111111111111111111111111110
4 비교연산자
4.1 대소비교 연산자
대소비교 연산자 : <, >, <=, >=,
두 피연산자의 크기를 비교하는 연산자
boolean형과 참조형을 제외한 자료형이 이용가능하다
4.2 등가비교 연산자
등가비교 연산자 : ==, !=
두 피연산자의 값이 같은지 다른지를 비교하는 연산자
수식
연산결과
x > y
x가y보다클때는true, 그외에는false
x < y
x가y보다작을때는true, 그외에는false
x >= y
x가 y보다 크거나 같을때는 true, 그 외에는 false
x <= y
x가 y보다 작거나 같을때는 true, 그 외에는 false
x == y
x가y보다같을때는true, 그외에는false
x != y
x가y보다다를때는true, 그외에는false
4.3 비트연산자
비트 연산자 : &, |, ^
이진 비트연산을 수행한다.
실수형을 제외한 나머지 기본 데이터형에 사용 가능하다
|(or 연산자) : 피연산자중 한쪽이 1(true)이면 1(true)
&(and 연산자) : 피연산자 둘다 1(true)이어야 1(true)
^(xor 연산자) : 피연산자의 값이 다를때에만 1(true)
이 비트 연산자는 연산 우선순위가 떨어지기 때문에 ()사 용을 하는 것이 좋다.
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
true
true
true
true
false
true
false
true
false
true
false
true
true
false
true
false
false
false
false
false
4.3 비트연산자
비트 연산자(계속) : &, |, ^
단순한 논리연산만을 하는 것은 아니다.
기존의 설명으로는 &, |는 피연산자 두 개를 다 검사하고,
&&, ||는 왼쪽에서 먼저 논리검사를 한후 결과가 나오면 오른쪽 피연산자를 검사하지 않는다는 정도였다.
&, |, ^ 연산자는 아래와 같이 정수형에도 사용이 가능하다.
식
2진수
10진수
3 | 5 = 7
00000011
3
| )
00000101
5
00000111
7
3 & 5 = 1
00000011
3
& )
00000101
5
00000001
1
3 ^ 5 = 6
00000011
3
^ )
00000101
5
00000110
6
4.3 비트연산자
예제
lass OperatorEx23{
public static void main(String[] args){
int x = 3;
int y = 5;
System.out.println("x| y = " + (x|y));
System.out.println("x& y = " + (x&y));
System.out.println("x^ y = " + (x^y));
System.out.println("true| false = " + (true|false));
System.out.println("true& false = " + (true&false));
System.out.println("true^ false = " + (true^false));
}
}
결과
x | y = 7
x & y = 1
x ^ y = 6
true | false = true
true & false = false
true ^ false = true
5 그외의 연산자
5.1 논리연산자
논리연산자 : &&, ||
논리연산자는 피연산자로 결과 값이 boolean형 값을 결 과로 하는 조건식 만을 허용한다.
&&가 ||보다 우선순위가 높으므로 ||와 &&를 혼용해서 사 용하는 경우에는 ()를 적절하게 사용하는 것이 중요하다.
|| : 피 연산자중 한쪽이 true면 모두 true
&& : 피 연산자중 양쪽이 모두 true이어야 true
5.1 논리연산자
예제
class OperatorEx24{
public static void main(String[] args){
char x = 'j';
if((x>='a' && x <='z') || (x>='A' && x <='Z')) {
System.out.println("유효한문자입니다.");
} else {
System.out.println("유효하지않은문자입니다.");
}
}
}
결과
유효한 문자입니다.
5.2 삼항연산자
삼항연산자 : (조건)?A:B
()내의 조건이 true이면 A연산을 수행하고
false이면 B의 연산을 수행하도록 하는 연산자 이다.
if문으로 변환이 가능하지만 코드의 간결함을 위해 자주 사용된다.
result = (x > 0)? (x+1):(x-1);
if문으로 변환!
if(x> 0){
result = x + 1;
}else{
result = x – 1;
}
5.2 삼항연산자
예제
class OperatorEx25{
public static void main(String[] args){
int x = 10;
int y = -10;
int absX= (x >= 0) ? x : -x;
int absY= (y >= 0) ? y : -y;
System.out.println("x=10일때, x의절대값은"+absX);
System.out.println("y=-10일때, y의절대값은"+absY);
}
}
결과
x=10일 때, x의 절대값은 10
y=-10일 때, y의 절대값은 10
5.3 대입연산자
대입연산자 : =
대입연산자는 변수에 값 또는 수식의 연산결과를 저장하는 데 사용된다.
대입연산자의 왼쪽에는 반드시 변수가 위치해야 하며 오른 쪽에는 리터럴이나 변수 또는 수식이 올 수 있다.
int i = 0;
i = 3;
i = i + 3;
3 = i + 3;// error! 대입연산자의왼쪽피연산자가변수가아니다!
final MAX = 3; // 변수앞에final을붙이면상수가된다.
MAX = 10; // error! 상수는값을바꿀수없다
5.3 대입연산자
대입연산자 : =
대입연산자는 모든 연산자들 중에서 가장 낮은 연산순위를 가지고 있다.
따라서 연산 중 제일 마지막에 수행된다.
연산 진행 방향이 오른쪽에서 왼쪽이기 때문에 x=y=3에서
y=3이 먼저 수행되고,
그 다음에 x=y가 수행된다.