프로그램에서 데이터를 처리하여 결과를 산출하는 것을 연산(Operations)이라고 한다.


- 연산자(Operator) : 어떤 연산을 나타내는 표시나 기호 

- 피연산자(Operand) : 해당 연산식에서 연산되는 데이터

- 연산식(Expressions) : 연산자와 피연산자를 이용하여 연산의 과정을 표현한 것



* 연산자의 종류


 유형

연산자

피연산자 수 

기능

예시 

과값

산술 연산자 

+, -, *, /, % 

2개 (이항)

사칙연산과 나머지 계산 

z = x + y

 숫자

부호 연산자

+, - 

1개 (단항) 

양수 및 음수의 표현

x = -x

 숫자

문자열 연산자

2개 (이항) 

두 문자열을 연결 

 "안녕" + "하세요"

문자열

대입 연산자

=, +=, -=, *=, /=

%=, &=, ^=, |=, <<=, >>= 

2개 (이항) 

좌변의 변수에 우변의 값을 대입

x += 1  (x = x + 1)

x &= y  (x = x & y)

 

증감 연산자

++, -- 

1개 (단항)

1만큼 증가(++) 또는 감소(--) 

++x (선증가 후연산)

x++ (선연산 후증가)

숫자 

비교 연산자 

==, !=, <, >, >=, <=, instanceof 

2개 (이항) 

값의 비교

x >= y  (x가 y보다 크거나 같은가)

boolean - true/false

논리 연산자 

!, &, |, &&, || 

단항 또는 이항

NOT(!), AND(&, &&), OR(|, ||) 연산

밑에 추가 설명

boolean - true/false

조건 연산자

(조건식) ? T : F 

3개 (삼항) 

조건식이 참이면 T, 거짓이면 F

(x > y) ? x : y

 

비트 연산자 

~, &, |, ^ 

단항 또는 이항

비트 XOR, AND, OR, NOT 연산 

밑에 추가 설명

숫자, boolean 

쉬프트 연산자 

<<, >>, >>> 

2개 (이항) 

비트 이동 연산자로 비트를 좌측, 우측으로 밀어서 이동 

밑에 추가 설명

숫자 




▶ 산술 연산자


1. 자바는 리터럴 간의 연산은 타입 변환 없이 계산한다.

ex) char c = 'A' + 1; // c에는 유니코드 66인 'B' 가 저장된다.

(But.) char c2 = c + 1; // c는 int타입으로 변환되고 1과 연산되므로 산출 타입은 int이다. 따라서 컴파일 에러.

위의 경우, c를 int타입으로 캐스팅(Casting)해서 char 타입으로 변환해야 한다.


2. 오버플로우 탐지 : 산출 타입(Type)으로 표현할 수 없는 값이 산출되면, 오버플로우가 발생하고 쓰레기값을 얻는다.


3. / 또는 % 연산자 사용 시 우측 피연산자는 0을 사용할 수 없다. 0으로 나누게 되면 예외(ArithmeticException)가 발생한다. 또한 실수 타입인 0.0 또는 0.0f로 나누면 예외가 발생하지 않고, / 연산의 결과는 Infinity(무한대) 값을 가지며, % 연산의 결과는 NaN(Not a Number)을 가진다. 이 때는 데이터가 엉망이 되므로 그 다음의 연산을 수행해선 안된다. 따라서 부동소수점(실수)을 입력받을 때 입력값의 NaN 여부를 조사하고 연산을 수행해야 한다.

(But.) NaN인지 조사할 때 == 연산자를 사용해선 안되며, Double.isNaN() 을 사용해야 한다. 그 이유는 NaN는 != 연산자를 제외한 모든 비교 연산자에서 false를 리턴하기 때문이다.



▶ 비교 연산자


1. 비교 연산자에서는 연산을 수행하기 전에 타입 변환을 통해 피연산자의 타입을 일치시킨다.


2. 예외 : 0.2 == 0.2f 의 경우 이진 포맷의 가수를 사용하는 모든 부동소수점 타입은 0.1을 정확히 표현할 수 없기 때문에 0.1f는 0.1의 근사값으로 나타나므로 피연산자를 모두 float 타입으로 강제 타입 변환한 후 비교 연산을 수행해야 한다.


3. String 객체의 문자열 비교할 때는 ==가 아닌 equlas() 메소드를 사용해야 한다. == 사용 시 객체의 번지값을 비교하므로 번지가 다른 객체일 경우 같은 문자열 상수라도 false가 나온다.



▶ 논리 연산자


1. AND (논리곱) - && 또는 & : 피연산자 모두 true일 경우 연산 결과로 true를 반환한다.


2. OR (논리합) - || 또는 | : 피연산자 중 적어도 하나가 true일 경우 연산 결과로 true를 반환한다.


3. XOR (배타적 논리합) - ^ : 피연산자가 하나는 true이고 다른 게 false일 경우에만 연산 결과는 true를 반환한다. (서로 다를 경우)


4. NOT (논리부정) - ! : 피연산자의 논리값을 바꾼다. true 이면 false ,  false이면 true로 변환한다.



▶ 비트 연산자


1. 비트 연산자는 데이터를 비트(bit) 단위로 연산한다.


2. 비트 반전 연산자, 논리 부정(~)

# 피연산자를 이진수로 표현했을 때, 0을 1로, 1은 0으로 반전한다.

# 정수 타입(byte, short, int, long)의 연산자에게만 사용된다.

# 연산 후, 부호 비트인 최상위 비트를 포함해서 모든 비트가 반전된다.

# 비트 반전 연산자의 산출 타입은 int 타입이다.

# 비트 반전 연산자의 산출값에 1을 더하면 부호가 반대인 정수를 얻는다.


3. 논리곱(AND) - & : 두 비트 모두 1일 경우에만 연산 결과가 1이 된다.


4. 논리합(OR) - | : 두 비트 중 적어도 하나가 1이면 연산 결과는 1이 된다.


5. 배타적논리합(XOR) - ^ : 두 비트 중 하나는 1이고 다른 하나가 0일 경우 연산 결과는 1이 된다.



▶ 쉬프트 연산자(비트 이동 연산자)


1. a << b : 정수 a를 이진법으로 표현했을 때, 각 비트를 b만큼 왼쪽으로 이동시키고 빈자리는 0으로 채워진다.


2. a >> b : 정수 a를 이진법으로 표현했을 때, 각 비트를 b만큼 오른쪽로 이동시키고 빈자리는 정수 a의 최상위 부호 비트와 같은 값으로 채워진다.


3. a >>> b : 정수 a의 각 비트를 b만큼 오른쪽으로 이동시키고 빈자리는 0으로 채워진다.



* 연산 방향 및 우선 순위


 연산자

연산 방향

우선 순위 

증감(++, --), 부호(+, -), 비트(~), 논리(!) 

← 

 높음












낮음

산술(*, /, %)

산술(+, -)

쉬프트(<<, >>, >>>) 

비교(<, >, <=, >=, instanceof) 

비교(==, !=) 

논리(&)

논리(^)

논리(|) 

논리(&&) 

논리(||) 

조건( ? : ) 

대입(=, +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>=, >>>=)





더블 버퍼링(Double Buffering)은 이중 버퍼링이라 불리기도 하며, 그래픽 객체에 이미지를 그릴 때 사용되는 기법이다.



Q) 왜 사용하는가 ? 


A) API를 시작하다보면 비트맵 이미지를 사용하게 된다. 그 때 이미지들이 전환되면서 영상처럼 부드럽게 움직일 거라 생각하지만 실제로 이미지들이 움직일 때마다 화면이 깜빡이는 현상이 눈에 들어온다. 쉽게 말하자면 아래와 같은 상황인 것이다.


▶ 게임 캐릭터이미지를 구현할 때 이미지를 움직이게 하고 싶다.

그러나 캐릭터가 띄엄띄엄 움직임과 동시에 깜빡거리는 화면

때문에 게임할 맛이 안난다.



그 이유는 컴퓨터가 이미지를 지웠다가 새 이미지를 다시 그리고 하는 방식을 반복하기 때문이다.


즉, 이미지를 그리는 데 시간이 소요되므로 이미지의 출력이 잦을수록 깜빡거리는 현상이 심해진다.


이에 대한 해결방안으로 버퍼 역할을 해줄 메모리 장치 컨텍스트(보이지 않는 화면)를 하나 더 사용하여 그곳에 이미지를 그리고, 기존화면을 유지하다가 이미지가 완성되면 실제 화면 장치 컨텍스트로 한꺼번에 베껴 그리는 것이다. 


아래는 이를 그림으로 표현한 것이다.






Q) 어떻게 사용하는가 ?


A) 자바를 예로 들자면,


//FIELDS

Image buffImage;

Graphics buffg;


//CONSTRUCTOR

(클래스명) {

repaint(); // 호출 시 repaint() -> update(g) -> paint(g) 순서로 메소드가 호출된다.

}


//METHODS

public void paint(Graphics g) {

if(buffg == null) {

buffImage = createImage(이미지 넓이, 이미지 높이); //버퍼링용 이미지 생성


if(buffImage == null) System.out.println("더블 버퍼링용 오프 스크린 생성 실패");

else buffg = buffImage.getGraphics(); 

//이미지를 생성해도 그래픽 객체를 얻어야 이미지 위에 그리고자하는 것을 그릴 수 있다.

}

update(g); // 이렇게 하면 반복적인 메소드 실행이 가능하다.

}


public void update(Graphics g) {


buffg.drawImage(그릴 이미지, 0, 0, this);


g.drawImage(buffImage, 0, 0, this); //실제 화면(g)으로 오프스크(buffg)에 그려진 이미지(buffImage)를 옮김.

}

자바의 실행 과정은 컴파일러에서 바이트 코드가 생성되고 자바 가상 기계를 통해 바이트 코드가 기계어로 변환된다.


Q) 왜 컴파일러와 자바 가상 기계라는 두 단계를 거치는 걸까?


A) 사용자가 모든 컴퓨터에서 응용 프로그램들을 다시 컴파일하지 않고 실행되게 하기 위해서이다.


Q) 자바 가상 기계는 별도로 설치해야 되는가?


A) 자바 가상 기계는 실제로 존재하는 컴퓨터가 아니라 가상 컴퓨터를 시뮬레이션하는 소프트웨어이다. 자바 가상 기계를 이용하면 하드웨어와 운영 체제를 프로그램으로부터 숨길 수 있다. 또한, 자바 가상 기계는 자바 컴파일러가 코드를 생성할 대상이 되는 추상화된 기계의 명세에 의하여 소프트웨어로 작성된다.


대부분의 프로그래밍 언어의 경우, 컴파일러에 의해 소스 코드 -> 기계어로 변환되어야 컴퓨터에서 실행할 수 있다. 그러나 자바 컴파일러는 특정한 컴퓨터를 위한 코드를 바로 생성하는 것이 아니라 자바 가상 기계(Java virtual machine)를 위한 바이트 코드(byte code)를 생성한다.


즉,

  

위와 같은 형태를 띄게 된다. 아래는 자바 실행 과정이다.



Hello.java (원본 파일)

Compiler

   Hello.class (바이트 코드)  

JVM 

  Hello(내용물)



Q) 자바 플랫폼(Platform)의 구성요소는 자바 가상 기계만 있는가?


A) 자바 플랫폼이란 프로그램이 실행되는 하드웨어(Hardware)나 소프트웨어(Software)의 환경을 뜻한다. 자바 플랫폼은 두 가지의 요소로 이루어져 있다.


- 자바 가상 기계 (JVM : Java Virtual Machine)

- 자바 응용 프로그래밍 인터페이스(API: Application Programming Interface)



Q) API란 무엇을 의미하는가?


A) 운영 체제(OS)나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 하여 응용 프로그램에서 사용할 수 있도록 만든 인터페이스이다. 파일 제어, 창 제어, 화상 처리, 문자 제어 등이 있다.



+ Recent posts