Java의 정석 제 3 장 연산자(Operator) Java 정석 2008. 4. 24 남궁성 강의 Chapter 3. 연산자(Operator) http://www.javachobo.com Java의 정석 제 3 장 연산자(Operator) 안녕하십니까? 자바의 정석의 저자 남궁성입니다. 지금부터 제3장 연산자에 대한 강의를 시작하겠습니다. 2008. 4. 24 남궁성 강의 castello@naver.com
Java 1. 연산자(Operator)란? 11. 비트연산자(&,|,^) 2. 연산자의 종류 12. 논리연산자(&&,||) 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 1. 연산자(Operator)란? 11. 비트연산자(&,|,^) 2. 연산자의 종류 12. 논리연산자(&&,||) 3. 연산자의 우선순위 13. 삼항연산자(? :) 4. 증감연산자(++,--) 14. 대입연산자(=,op=) 5. 부호연산자(+,-)와 논리부정연산자(!) 6. 비트전환연산자(~) 7. 이항연산자의 특징 다음과 같은 순서로 강의가 진행될 것인데요. 책의 내용을 강의에 알맞은 형태로 재구성하였습니다. 8. 나머지 연산자(%) 9. 쉬프트연산자(<<,>>,>>>) 10. 비교연산자(>,<,>=,<=,==,!=)
1. 연산자(Operator)란? a + b Java - 어떠한 기능을 수행하는 기호(+,-,*,/ 등) 의 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 1. 연산자(Operator)란? ▶ 연산자(Operator) - 어떠한 기능을 수행하는 기호(+,-,*,/ 등) ▶ 피연산자(Operand) - 연산자의 작업 대상(변수,상수,리터럴,수식) 연산자란... 어떠한 기능을 수행하는 기호를 말합니다. 예를 들면 +는 덧셈’이라는 기능을 수행하는 기호죠. 피연산자는 연산자의 작업대상을 말합니다. 예를 들어 a + b라는 식이 있다고 할 때... +는 연산자이고, 연산자가 덧셈을 수행할 대상인 a와 b는 피연산자입니다. a + b
2. 연산자의 종류 Java : + - (타입) ++ -- ~ ! 산술 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 2. 연산자의 종류 ▶ 단항 연산자 : + - (타입) ++ -- ~ ! 산술 : + - * / % << >> >>> ▶ 이항 연산자 비교 : > < >= <= == != 논리 : && || & ^ | ▶ 삼항 연산자 : ? : 연산자의 종류는 크게 단항, 이항, 삼항, 대입 연산자로 나눌 수 있습니다. 단항, 이항, 삼항은 피연산자의 개수에 따라 분류한 것인데요. 단항연산자는 1항연산자라고도 하는데요. 단항연산자는 연산에 필요한 피연산자가 1개, 이항연산자는 피연산자가 2개, 삼항연산자는 피연산자가 3개라는 것을 의미합니다. 단항연산자에는 이러한 연산자들이 있습니다. 여기의 플러스 기호와 마이너스 기호는 덧셈, 뺄셈 연산자가 아니라... 피연산자의 부호를 바꿔주는 부호 연산자입니다. 기호는 같지만 피연산자의 개수에 따라 부호연산자가 되기도 하고 덧셈연산자가 되기도 하는 것입니다. 이 것은 형변환 연산자입니다. 형변환 연산자는 괄호안에 변환하고자하는 타입을 적어주는데요. 피연산자의 타입을 지정한 타입으로 형변환합니다. 나머지 연산자들에 대해서는 앞으로 자세히 설명할 것이고요. 이항연산자는 산술, 비교, 논리 이렇게 세가지 그룹으로 다시 나뉩니다. 산술연산자는 은 덧셈뺄셈과 같은 사칙연산을 수행하는 연산자 들이고요. 비교연산자는 값의 크기와 같고 다름을 비교하는 연산자입니다. 논리연산자는 조건식의 논리적 결합에 사용됩니다. 삼항연산자는 단 하나 뿐이고요. 우선순위는 단항이 제일 높고, 그 다음에 이항, 삼항, 대입연산자의 순입니다. 대입연산자는 모든 연산이 끝난 다음에 그 결과를 저장하는데 사용되기 때문에 우선순위가 제일 낮습니다. ▶ 대입 연산자 : =
3. 연산자의 우선순위(1/4) Java 정석 의 Chapter 3. 연산자(Operator) http://www.javachobo.com 3. 연산자의 우선순위(1/4) 이것은 연산자의 우선순위를 정리한 표입니다. 우선순위가 높은 것 부터 낮은 것의 순으로 되어 있고요. 같은 줄의 연산자들은 우선순위가 같습니다. 아까 간단히 얘기한 것 처럼 우선순위가 높은 것 부터 낮은 것 순으로 나열하면 단항, 이항, 삼항, 대입 연산자의 순이고요. 이항 연산자 중에는 산술, 비교, 논리 연산자의 순입니다. 이 표를 보고 이 순서를 어떻게 다외우나... 싶겠지만... 사실 여러분들은 이미 다 알고 있기 때문에... 몇가지 주의할 점만 기억해두시면 됩니다. 그리고 우선순위 뿐만아니라 연산방향에 대해서도 알아두셔야하는데요. 연산방향은... 같은 우선순위의 연산이 있을 때 연산을 수행하는 방향을 말합니다. 일단 여기서는 단항과 대입연산자를 제외하고는 연산진행방향이 오른쪽에서 왼쪽이라는 것만 기억해두세요. instanceof는 참조형변수의 타입을 체크하는 연산자인데요. 이번 장에서는 다루지 않고 나중에 7장 객체지향개념2에서 설명할 것이까 신경쓰지마세요.
3. 연산자의 우선순위(2/4) Java - 괄호의 우선순위가 제일 높다. - 산술 > 비교 > 논리 > 대입 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 3. 연산자의 우선순위(2/4) - 괄호의 우선순위가 제일 높다. - 산술 > 비교 > 논리 > 대입 - 단항 > 이항 > 삼항 - 연산자의 연산 진행방향은 왼쪽에서 오른쪽(→)이다. 단, 단항, 대입 연산자만 오른쪽에서 왼쪽(←)이다. 연산자의 우선순위에 대해서는 여기 정리된 내용만 정확히 기억하고 계셔도 별 어려움이 없습니다. 연산진행방향이 왼쪽에서 오른쪽이라는 얘기는... 같은 우선순위의 연산자가 여러 개 있을 때 왼쪽의 연산자부터 계산한다는 뜻입니다. 예를 들어 3*4*5라는 식이 있을 때... 같은 우선순위의 연산자가 2개 있잖아요. 이 때 어떤 연산을 먼저 수행할 것인지가 연산방향에 의해서 결정됩니다. *은 산술연산자니까 연산방향이 왼쪽에서 오른쪽이죠? 그래서 왼쪽의 3*4가 먼저 계산되고 그 다음에 3*4의 계산결과 * 5가 계산됩니다. 반면에 x=y=3이라는 수식이 있을 때, 대입연산자는 연산방향이 왼쪽에서 오른쪽이니까 두 개의 대입연산자 중에서 오른쪽에 있는 대입연산자가 먼저 수행되어서 y에 3이 저장되고, 그 다음의 대입연산자가 수행되어 y의 값이 x에 저장됩니다. 3 * 4 * 5 x = y = 3
3. 연산자의 우선순위(3/4) Java - 상식적으로 생각하라. 우리는 이미 다 알고 있다. ex1) –x + 3 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 3. 연산자의 우선순위(3/4) - 상식적으로 생각하라. 우리는 이미 다 알고 있다. ex1) –x + 3 단항 > 이항 ex2) x + 3 * y 곱셈, 나눗셈 > 덧셈, 뺄셈 ex3) x + 3 > y - 2 산술 > 비교 ex4) x > 3 && x < 5 비교 > 논리 ex5) int result = x + y * 3; 항상 대입은 맨 끝에
4. 연산자의 우선순위(4/4) Java - 그러나 몇 가지 주의해야 할 것이 있다. 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 4. 연산자의 우선순위(4/4) - 그러나 몇 가지 주의해야 할 것이 있다. 1. <<, >>, >>>는 덧셈연산자보다 우선순위가 낮다. ex5) x << 2 + 1 x << (2 + 1) 과 같다. 2. ||, |(OR)는 &&, &(AND)보다 우선순위가 낮다. 지금까지 살펴본 것과 같이 대부분의 경우 연산자의 우선순위를 상식적으로 판단할 수 있습니다. 그러나 상식적으로 판단하기 어려운 경우도 있어서 이런 경우만 잘 기억해두시면 됩니다. 쉬프트연산자는 2의 n제곱으로 곱하거나 나눈 결과를 돌려주는 연산자입니다. 그래서, 곱셈나눗셈이 덧셈보다 우선순위가 높으니까 쉬프트연산자도 덧셈보다 우선순위가 높을 것이라고 생각하기 쉽지만 쉬프트연산자는 덧셈이나 뺄셈연산자보다 우선순위가 낮습니다. 그 다음에... 논리연산자인 OR과 AND는 우선순위가 같을 것 같지만 OR는 AND보다 우선순위가 낮습니다. 그래서 이 식은 아래의 괄호를 사용한 식과 동일합니다. 이처럼... 한 수식에 AND와 OR가 같이 사용되는 경우에는 괄호를 사용해서 우선순위를 알아보기 쉽게 해야 실수가 없습니다. ex6) x < -1 || x > 3 && x < 5 x < -1 || (x > 3 && x < 5) 와 같다.
4. 증감연산자 - ++, -- Java 정석 전위형 j = ++i; ++i; j = i; 값이 참조되기 전에 증가시킨다. 의 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 4. 증감연산자 - ++, -- ▶ 증가연산자(++) : 피연산자의 값을 1 증가시킨다. ▶ 감소연산자(--) : 피연산자의 값을 1 감소시킨다. int i = 5; int j = 0; 전위형 j = ++i; ++i; j = i; 값이 참조되기 전에 증가시킨다. 후위형 j = i++; i++; 값이 참조된 후에 증가시킨다. 증감연산자는 단항연산자로 피연산자의 값을 1증가 또는 감소시킵니다. 이 연산자의 특이한 점은 피연산자의 오른쪽 또는 왼쪽에 놓을 수 있으며 연산자의 위치에 따라 결과가 달라질 수 있습니다. 증감연산자를 피연산자의 왼쪽에 놓은 것을 전위형, 오른쪽에 놓은 것을 후위형 이라고하는데요. 전위형은 값이 참조되기 전에 증가시키고, 후위형은 값이 참조된 후에 증가시킵니다. 무슨 얘기냐면... 예를 들어 int타입의 변수 i와 j가 있을 때.... i에 5를 저장하고, j에는 0을 저장한 다음에... j = ++i; 이 식이 수행되면... ++i에 의해서 변수 i에 저장되어 있는 값이 1증가하고 i의 값을 참조합니다. 그래서 i의 값이 5에서 6으로 1증가하고, i의 값을 읽어옵니다. 그 다음에 대입연산자에 의해서 ++i의 결과가 j에 저장됩니다. 전위형과 반대로 후위형은... 변수의 값이 참조된 후에 증가되기 때문에... i++이 수행되면, 먼저 i의 값인 5를 읽어온 다음에 i의 값을 증가 시켜서 6이됩니다. i에 저장된 값은 6이되었지만, i++의 수행결과는 5입니다. 그래서 대입연산자에 의해서 5가 변수 j에 저장되는 것입니다. 식이 좀 복잡해서 이해하기 어려운 경우에는 이처럼... 증감연산자를 식에서 분리시키세요. 그러면 보다 쉽게 이해하실 수 있을 겁니다. 증감연산자가 식에 포함된 경우에는... 전위형과 후위형이 차이가 있지만... 이처럼 단독적으로 사용되었을 때는 전위형과 후위형의 차이가 전혀 없습니다. 단순히 변수의 값을 1 증가시킬 뿐입니다. ++i는 i = i +1;과 같은 결과를 얻지만, ++i가 속도도 더 빠르고 코드를 간결하게 작성할 수 있기 때문에 더 많이 사용합니다. 자세한 내용은 책에 나와 있으니 참고하시기 바랍니다.
5. 부호연산자(+,-)와 논리부정연산자(!) Java ‘-’는 피연산자에 -1을 곱한다. 의 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 5. 부호연산자(+,-)와 논리부정연산자(!) ▶ 부호연산자(+,-) : ‘+’는 피연산자에 1을 곱하고 ‘-’는 피연산자에 -1을 곱한다. ▶ 논리부정연산자(!) : true는 false로, false는 true로 피연산자가 boolean일 때만 사용가능 boolean power = false; power = !power; int i = -10; i = +i; i = -i;
6. 비트전환연산자 - ~ Java - 정수를 2진수로 표현했을 때, 1을 0으로 0은 1로 바꾼다. 정수형에만 사용가능. 의 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 6. 비트전환연산자 - ~ - 정수를 2진수로 표현했을 때, 1을 0으로 0은 1로 바꾼다. 정수형에만 사용가능.
7. 이항연산자의 특징(1/7) Java - int보다 크기가 작은 타입은 int로 변환한다. 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 7. 이항연산자의 특징(1/7) 이항연산자는 연산을 수행하기 전에 피연산자의 타입을 일치시킨다. - int보다 크기가 작은 타입은 int로 변환한다. ( byte, char, short → int ) - 피연산자 중 표현범위가 큰 타입으로 형변환 한다. byte + short → int + int → int char + int → int + int → int 지금까지 단항연산자에 대해서 알아봤고요. 이제 이항연산자에 대해서 알아볼 차례입니다. 연산자의 대부분은 이항연산자이고 이들의 공통적인 특징이 있습니다. 이항연산자를 하나하나 살펴보기 전에...이들의 특징에 대해서 자세히 살펴보도록 하겠습니다. 먼저 모든 이항연산자는 연산을 수행하기 전에 피연산자의 타입을 서로 일치시킵니다. int보다 크기가 작은 타입의 경우에는 int로 변환하고요. 피연산자중 표현범위가 큰 타입으로 형변환 합니다. int보다 작은 타입인 byte, char, short인 경우에는 int로 변환합니다. boolean도 int보다 작은 타입이지만, boolean은 형변환이 안되니까 제외됩니다. 예를 들어서... float + int → float + float → float long + float → float + float → float float + double → double + double → double
7. 이항연산자의 특징(2/7) Java byte a = 10; byte b = 20; byte c = a + b; 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 7. 이항연산자의 특징(2/7) byte a = 10; byte b = 20; byte c = a + b; byte + byte → int + int → int byte c = (byte)a + b; // 에러 byte c = (byte)(a + b); // OK
7. 이항연산자의 특징(3/7) Java int a = 1000000; // 1,000,000 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 7. 이항연산자의 특징(3/7) int a = 1000000; // 1,000,000 int b = 2000000; // 2,000,000 long c = a * b; // c는 2,000,000,000,000 ? // c는 -1454759936 !!! int * int → int 이와 같이 int타입의 변수, a와 b가 있고, 각각 백만과 2백만이 저장되어 있을 때... a * b의 결과를 long타입의 변수 c에 저장하면 어떻게 될까요... long타입의 변수는 2곱하기 10의 12제곱값을 저장할 수 있기 때문에 문제가 없어보이지만... 변수 c에는 2곱하기 10의 12제곱이 저장되는 것이 아니라 엉뚱한 값이 저장됩니다. 왜냐면... int 곱하기 int의 결과는 int이기 때문에 연산과정에서 이미 정수의 오버플로우가 발생합니다. 그래서 에러가 발생하지는 않지만, 우리가 원하는 것과는 다른 값이 됩니다. 아무리 저장할 변수의 타입이 long이라 하더라도 이미 오버플로우가 발생한 값을 long타입의 변수에 저장하는 것이기 때문에 int타입의 변수에 저장하는 것과 차이가 없습니다. 그래서 이럴 때는 a나 b 중의 하나를 long타입으로 형변환하면 됩니다. 그러면 연산할 때 둘다 long으로 변환되어 계산되고 최종결과가 long타입의 값이기 때문에 변수 c에 올바른 값이 저장됩니다. long c = (long)a * b; // c는 2,000,000,000,000 ! long * int → long * long → long
7. 이항연산자의 특징(4/7) Java long a = 1000000 * 1000000; // a는 -727,379,968 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 7. 이항연산자의 특징(4/7) long a = 1000000 * 1000000; // a는 -727,379,968 long b = 1000000 * 1000000L; // b는 1,000,000,000,000 int c = 1000000 * 1000000 / 1000000; // c는 -727 이번엔 연산순서에 관한건데요... 여러분들 알고 계신것처럼 곱하기와 나누기는 연산우선순위가 같기 때문에... 연산우선순위가 같은 경우에 어떻게 한다고요... 연산진행방향에 따라 연산순서가 결정되죠... 그래서 곱셈이 먼저 계산되고, 그 다음에 나눗셈이 계산됩니다. 사실 이 경우에는 곱셈을 먼저하나 나눗셈을 먼저하나 값이 같아야하는데요. 그렇지 않습니다. 위의 식에서는 곱셈에서 overflow가 발생하기 때문에 앞서 살펴본것과 같이 -7억 이렇게 됩니다. 그다음에 다시 백만으로 나누면 1이 되는 것이 아니라 -727이 됩니다. -7억을 백만으로 나누니까 뒤에 6자리가 잘려나간 것입니다. 정수형의 나눗셈결과는 정수값이고... 반올림은 발생하지 않는 다는 것을 다시한번 확인하세요. 아래의 식과 같이 나눗셈을 먼저하는 경우에는 overflow가 발생하지않기 때문에 변수 d에는 우리가 예상했던 값인 백만이 저장됩니다. 이처럼... 연산의 순서에 따라서도 값이 달라질 수 있다는 것에 주의하시기 바랍니다. int d = 1000000 / 1000000 * 1000000; // d는 1,000,000
7. 이항연산자의 특징(5/7) Java char c1 = ‘a’; char c2 = c1 + 1; // 에러 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 7. 이항연산자의 특징(5/7) 문자 코드 ... 48 1 49 2 50 A 65 B 66 C 67 a 97 b 98 c 99 char c1 = ‘a’; char c2 = c1 + 1; // 에러 char c2 = (char)(c1 + 1); // OK char c2 = ++c1; // OK int i = ‘B’ – ‘A’; int i = ‘2’ – ‘0’;
7. 이항연산자의 특징(6/7) Java float pi = 3.141592f; 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 7. 이항연산자의 특징(6/7) float pi = 3.141592f; float shortPi = (int)(pi * 1000) / 1000f; (int)(3.141592f * 1000) / 1000f; (int)(3141.592f) / 1000f; 3141 / 1000f; 이 번에 설명드릴 내용은 실수의 소수점 아래 자리수를 조절하는 방법입니다. float타입의 변수 pi에 3.141592가 저장되어 있을 때... pi값에서 소수점 3자리까지만 얻어내려면 이렇게 합니다. pi에 천을 곱하고, int로 형변환 한다음에... 다시 1000f로 나누면 됩니다. 계산과정을 단계별로 살펴보면... 만일 3141을 1000f가 아닌 1000으로 나누었다면 어떻게 될까요? 3.141이 아닌 3이 됩니다. int와 int의 연산은 그 결과가 int이기 때문이죠. 3141.0f / 1000f 3.141f
7. 이항연산자의 특징(7/7) Java * Math.round() : 소수점 첫째자리에서 반올림한 값을 반환 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 7. 이항연산자의 특징(7/7) * Math.round() : 소수점 첫째자리에서 반올림한 값을 반환 float pi = 3.141592f; float shortPi = Math.round(pi * 1000) / 1000f; Math.round(3.141592f * 1000) / 1000f; Math.round(3141.592f) / 1000f; 이번에는 실수의 소수점 아래 자리수를 조절할 때 반올림 된 값을 얻어오는 방법에 대해서 알아보겠습니다. 전에는 int로 형변환을 하기 때문에 반올림이 아닌 버림이 되었는데요. Math클래스의 round메서드를 이용하면 잘라낸 자리 다음자리에서 반올림된 값을 얻을 수 있습니다. round()메서드는 소수점 첫째자리에서 반올림한 정수값을 반환합니다. 아까와 같이 float타입의 변수 pi가 있을 때... 소수점 넷째자리에서 반올림된 소수점 세자리의 실수를 얻는 방법은 다음과 같습니다. ... 아까 int로 형변환 했을 때는 소수점 아래는 무조건 버리기 때문에 3141이 되었지만 round메서드는 소수점 첫째자리에서 반올림을 하니까 3142가 됩니다. round메서드의 반환값은 float가 아닌 정수라는 것 확인하시고요. 그 이후는 전과 다르지 않습니다. 3142 / 1000f; 3142.0f / 1000f 3.142f
8. 나머지연산자 - % Java 나누기한 나머지를 반환한다. 홀수, 짝수 등 배수검사에 주로 사용. 의 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 8. 나머지연산자 - % 나누기한 나머지를 반환한다. 홀수, 짝수 등 배수검사에 주로 사용. int share = 10 / 8; int remain = 10 % 8; 10 % 8 → 2 10 % -8 → 2 -10 % 8 → -2 -10 % -8 → -2
9. 쉬프트연산자 - <<, >>, >>> Java 의 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 9. 쉬프트연산자 - <<, >>, >>> 2n으로 곱하거나 나눈 결과를 반환한다. 곱셈, 나눗셈보다 빠르다. x << n 은 x * 2n과 같다. x >> n 은 x / 2n과 같다. 8 << 2 는 8 * 22과 같다. 8 >> 2 는 8 / 22과 같다. 그 다음은 쉬프트 연산자인데요. 정수값을 2진수로 표현했을 때 각 자리를 지정된 자리수 만큼 오른쪽 또는 왼쪽으로 쉬프트, 즉 이동시키기 때문에 쉬프트 연산자라는 이름이 붙여졌습니다. 2진수값의 자리를 이동하면 2의 n제곱으로 곱하거나 나눈 결과를 얻을 수 있습니다. 곱셈이나 나눗셈연산자를 사용해도 되는데 굳이 쉬프트 연산자를 사용하는 이유는 연산속도 때문입니다. 쉬프트 연산자가 곱셈이나 나눗셈 연산자보다 연산속도가 훨씬 빠르기 때문에 빠른 처리속도가 요구되는 그래픽처리와 같은 곳에 주로 사용됩니다. 이러한 경우를 제외하고는 가능하면, 곱셈이나 나눗셈 연산자를 사용하세요. x 왼쪽 쉬프트 n은 피연산자 x를 2진수로 표현했을 때 왼쪽으로 n자리를 이동하라는 의미입니다. 그 결과는 x곱하기 2의 n제곱과 같습니다. x 오른쪽 쉬프트 n은 피연산자 x를 2진수로 표현했을 때 오른쪽으로 n자리를 이동하라는 의미입니다. 그 결과는 x나누기 2의 n제곱과 같습니다. 예를 들어 정수 8을 왼쪽으로 2자리 쉬프트 연산을 수행하면, 8 곱하기 2의 2제곱과 같은 결과인 32를 결과로 얻습니다. 8을 오른쪽으로 2자리 쉬프트 연산을 수행하면, 8나누기 2의 2제곱과 같은 결과인 2를 결과로 얻습니다. 쉬프트 연산은 말보다 그림을 보면 이해가 쉬운데요. 여기서 제가 표를 또 제시하는 것보다 책의 54페이지에 있는 표3-9를 보시는 것이 좋을 것 같습니다. * 참고 : p.54 표3-9 쉬프트연산의 예
10. 비교연산자 - > < >= <= == != Java 의 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 10. 비교연산자 - > < >= <= == != 피연산자를 같은 타입으로 변환한 후에 비교한다. 결과 값은 true 또는 false이다. - 기본형(boolean제외)과 참조형에 사용할 수 있으나 참조형에는 ==와 !=만 사용할 수 있다. 비교 연산자... 비교연산자는 두 피연산자의 값을 비교하는 것인데요. 두 피연산자의 크고 작음, 같고 다름을 비교해서 그 결과를 true 또는 false로 반환합니다. 비교연산자도 이항연산자니까... 피연산자들의 타입을 같게 변환한 다음에 비교하겠죠. 비교연산자는 boolean을 제외한 기본형과 참조형에 사용할 수 있습니다. 참조형 변수는 객체의 주소를 저장하기 때문에... 크기비교는 의미가 없고요. 두 참조형 변수가 같은 객체를 참조하고 있는지, 아닌지를 확인 할 수 있는 같음과 같지않음을 비교하는 연산자만 사용할 수 있습니다.
10. 비교연산자 - > < >= <= == != Java 의 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 10. 비교연산자 - > < >= <= == != ‘A’ < ‘B’ → 65 < 66 → true ‘0’ == 0 → 48 == 0 → false ‘A’ != 65 → 65 != 65 → false 10.0d == 10.0f → 10.0d == 10.0d → true 0.1d == 0.1f → 0.1d == 0.1d → true? false? 자 이제 몇가지 예를 통해서 비교연산자의 연산과정을 살펴보겠습니다. 문자 A가 문자 B보다 작은지를 비교하는 식인데요. char와 char의 연산이니까 비교하기 전에 앞서 int로 형변환됩니다. 그래서 문자 A의 코드값인 65와 문자 B의 코드값인 66을 비교해서 65가 66보다 작으니까 최종적으로 true를 결과로 얻습니다. 이 식은 문자 0과 숫자 0이 같은지를 비교하는 것인 데요. 여기서도 문자 0은 int로 변환되어 문자 0의 코드 값인 48로 변환됩니다. 그 다음에 48과 0을 비교해서 같지 않으니까 결과가 false가 됩니다. 그 다음에... 문자 A와 숫자 65가 같지 않은지를 확인하는 식인데요. 여기서도 문자 A는 int로 변환되어 65가 됩니다. 그리고 65와 65가 같지 않은지를 비교하니까 그 결과가 false가 됩니다. 이 식은 10.0d와 10.0f가 같은지를 비교하는 식인데요. 두 피연산자의 타입이 다르니까 둘 중에 큰 타입으로 형변환된 다음, 10.0d와 10.0d를 비교해서 그 결과가 true가 됩니다. 그려면 0.1d와 0.1f가 같은지를 비교하는 이 식의 결과는 어떻게 될까요? true일 까요? false일까요? true일 것 같지만 그 결과는 false입니다. 이 처럼... float와 double간의 비교는 true일 수도 있고 false일 수도 있습니다. 왜냐면 실수는 정수처럼 정확한 값이 아닌 근사값의 형태로 표현되기 때문에 float를 double로 형변환 했을 때 값이 달라질 수 있습니다. 이경우 사실 굉장히 작은, 1억분의 1정도의 오차이지만... 비교연산자로 비교했을 때 분명히 같은 값은 아니기 때문에 false를 결과로 얻은 것입니다. 그래서... 이러한 문제를 해결하기 위해서 float와 double을 비교할 때는 float를 double로 형변환 하는 것이 아니라 오히려 double을 float로 형변환한 다음에 비교해야합니다. double d = (double)0.1f; System.out.println(d); // 0.10000000149011612 (float)0.1d == 0.1f → 0.1f == 0.1f → true
11. 비트연산자 - & | ^ Java 정석 - 피연산자를 비트단위로 연산한다. 의 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 11. 비트연산자 - & | ^ - 피연산자를 비트단위로 연산한다. 실수형(float, double)을 제외한 모든 기본형에 사용가능 ▶ OR연산자(|) : 피연산자 중 어느 한 쪽이 1이면 1이다. ▶ AND연산자(&) : 피연산자 양 쪽 모두 1이면 1이다. ▶ XOR연산자(^) : 피연산자가 서로 다를 때 1이다. x y x | y x & y x ^ y 1 비트 연산자는 피연산자를 비트단위로 연산합니다. 다시 말하면... 두 피연산자의 2진수로 표현했을 때 각 비트 별로 연산을 하는 것입니다. 비트 연산자는 실수형을 제외한 모든 기본형에 사용할 수 있습니다. OR는 어느 한쪽이 1이기만 하면 1이고 그 외에는 0을 결과로 얻습니다. AND는 둘 다 1이어야만 1을 결과로 얻고 그 외에는 0을 결과로 얻습니다. XOR는 Exclusive OR라는 의미인데요. Exclusive가 배타적이라는 의미라서 배타적 OR라고도 합니다. 배타적이라는게 무엇입니까 서로 다르다는 뜻이잖아요? 그래서 XOR는 두 피연산자의 비트가 서로 다를 때만 1이고 같을 때는 0입니다.
11. 비트연산자 - & | ^ Java 정석 의 Chapter 3. 연산자(Operator) http://www.javachobo.com 11. 비트연산자 - & | ^ 식 3 OR 5의 연산 결과는 7입니다. 왜 7이냐면... 3과 5를 이진수로 표현했을 때 3과 5의 각 비트를 OR연산하면... 두 피연산자의 각 비트 중에서 어느 한쪽이 1이기만 하면 1을 결과로 얻기 때문에... 이진수 111을 결과로 얻습니다. 이진수 111은 10진수로 7입니다. 식 3 AND 5의 연산결과는 1인데... AND는 두 피연산자의 비트 중에서 둘다 1일 때만 1이기 때문에... 각 비트를 연산하면 1을 결과로 얻습니다. 마지막으로 3 XOR 5를 연산하면... 두 피연산자의 비트 중에서 서로 다른 경우인 마지막의 두번째와 세번째 비트만 1이 되어서 이진수 110을 결과로 얻습니다. 이진수 110은 10진수로 6이므로 결과가 6이 됩니다.
11. 비트연산자 - & | ^ Java 정석 0x185C 0x185C >> 4 → 0x0185 0x000F 의 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 11. 비트연산자 - & | ^ 0x185C 1 0x185C >> 4 → 0x0185 1 0x000F 1 0x0185 & 0x000F → 0x0005 1 0x185C >> 4 & 0x000F → 0x0005 0x185C >> 8 & 0x000F → 0x0008 12345 / 100 % 10 → 3 12345 / 1000 % 10 → 2
12. 논리연산자 - && || Java 정석 피연산자가 반드시 boolean이어야 하며 연산결과도 boolean이다. 의 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 12. 논리연산자 - && || 피연산자가 반드시 boolean이어야 하며 연산결과도 boolean이다. &&가 || 보다 우선순위가 높다. 같이 사용되는 경우 괄호를 사용하자 ▶ OR연산자(||) : 피연산자 중 어느 한 쪽이 true이면 true이다. ▶ AND연산자(&&) : 피연산자 양 쪽 모두 true이면 true이다. x y x || y x && y true false
12. 논리연산자 - && || Java 정석 int i = 7; i > 3 && i < 5 의 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 12. 논리연산자 - && || int i = 7; x y x || y x && y true false i > 3 && i < 5 i > 3 || i < 0 char x = ‘j’; int타입의 변수 i를 선언하고 7을 저장했을 때... i가 3보다 크고 i가 5보다 작다...라는 식의 결과는 어떻게 될까요. 이 식에는 연산자가 모두 3개가 있죠. 비교연산자 2개하고 논리연산자 1개인데요. 논리연산자보다 비교연산자가 우선순위가 높고.... 비교연산자는 연산의 진행방향이 왼쪽에서 오른쪽이니까... 왼쪽의 식이 먼저 계산됩니다. i의 값이 7이니까 i가 3보다 크다는 식은 true이고 i가 5보다 작은지를 비교하는 식은 false가 되겠죠. 그래서 true && false이니까... 최종결과는 false입니다. 이 식에서는 i가 7이니까 왼쪽식은 true가 되고요. 오른쪽 식은 false가 되겠죠. 그래서 true || false이니까... 최종결과는 true입니다. 그런데...사실 ||의 경우... 왼쪽 피연산자가 true인 경우에는 최종결과가 무조건 true이므로 오른쪽 피연산자의 값을 확인하지 않습니다. 즉 i가 0보다 작은지 비교하지 않는 다는 것이지요. &&의 경우에는 왼쪽 피연산자가 false이면 오른쪽 피연산자의 값과 상관없이 최종결과가 false이니까. 오른쪽 피연산자의 값을 확인하지 않습니다. 왼쪽의 피연산자값만으로 효율적인 연산을 하는 것이지요. 그래서 ||의 경우에는 true일 확률이 높은 피연산자를 왼쪽에 놓고... &&의 경우에는 false일 확률이 높은 피연산자를 왼쪽에 놓는 것이 좋습니다. char타입의 변수 x에 문자 ‘j’가 저장되어 있을 때... 이 식은 변수 x에 저장된 문자가 소문자인지를 확인하는 식입니다. 최종결과가 true겠지요? 이 식은 변수 x에 저장된 문자가 소문자 또는 대문자인지를 확인하는 식입니다. 만일 숫자인지 확인하려면 어떻게 하면 될까요? a와 z대신에 0과 9를 사용하면 되겠죠. x >= ‘a’ && x <= ‘z’ (x >= ‘a’ && x <= ‘z’) || (x >= ‘A’ && x <= ‘Z’)
13. 삼항연산자 - ? : Java 정석 조건식의 연산결과가 true이면 ‘식1’의 결과를 반환하고 Chapter 3. 연산자(Operator) http://www.javachobo.com 13. 삼항연산자 - ? : 조건식의 연산결과가 true이면 ‘식1’의 결과를 반환하고 false이면 ‘식2’의 결과를 반환한다. (조건식) ? 식1 : 식2 if(x>=0) { absX = x; } else { abxX = -x; } int x = -10; int absX = x >= 0 ? x : -x; int score = 50; char grade = score >= 90 ? ‘A’ : (score >= 80? ‘B’ : ’C’);
14. 대입연산자 - = op= Java 정석 오른쪽 피연산자의 값을 왼쪽 피연산자에 저장한다. Chapter 3. 연산자(Operator) http://www.javachobo.com 14. 대입연산자 - = op= 오른쪽 피연산자의 값을 왼쪽 피연산자에 저장한다. 단, 왼쪽 피연산자는 상수가 아니어야 한다. int i = 0; i = i + 3; final int MAX = 3; 드디어 연산자의 마지막인데요. 대입연산자입니다. 대입연산자는 그동안 계속 나왔기 때문에 잘알고 계실겁니다. 그래도 간단히 설명하고 넘어가도록 하겠습니다. 대입연산자는 오른쪽 피연산자의 값을 왼쪽 피연산자에 저장합니다. 이 식은 오른쪽 피연산자인 0을 왼쪽 피연산자인 int타입의 변수 i에 저장합니다. 그 다음에 i에 저장된 값을 참조해서 3을 더한 결과를 다시 변수 i에 저장합니다. 그래서 변수 i에는 3이 저장되겠죠. 변수를 선언할 때 final을 붙이면 상수가 됩니다. 상수는 이처럼 선언과 동시에 값을 저장해야하는 데요. 한번 저장된 값은 바꿀 수 없습니다. 그래서 이와 같이 대입 연산자를 이용해서 다른 값을 저장하려고 하면 에러가 발생합니다. 대입연산자를 다른 연산자와 결합된 형태로 간략히 표현할 수 있는데요. 예를 들어 i = i + 3을 왼쪽과 같이 간단하게 할 수 있다는 겁니다. 하나만 기억해 두면 나머지는 응용하면 되니까 어렵지 않으실 것이고요. 한가지 주의해야할 점은... 맨 아래의 식인데요. 왼쪽의 식을 오른쪽의 식으로 변환할 때 괄호를 사용해야한다는 것을 기억해두시기 바랍니다. MAX = 10; // 에러
감사합니다. http://www.javachobo.com Java 정석 의 정석 Chapter 3. 연산자(Operator) http://www.javachobo.com 감사합니다. 더 많은 동영상강좌를 아래의 사이트에서 구하실 수 있습니다. http://www.javachobo.com 이것으로 제 3장 연산자에 대한 강의를 모두 마치겠습니다. 긴 강의 듣느라 고생많으셨습니다. 감사합니다. 이 동영상강좌는 비상업적 용도일 경우에 한해서 저자의 허가없이 배포하실 수 있습니다. 그러나 일부 무단전제 및 변경은 금지합니다. 관련문의 : 남궁성 castello@naver.com