이세개발
article thumbnail
Published 2023. 4. 16. 22:00
이것이java다 3.3 단항 연산자 legacy

단항 연산자는 피연산자가 단 하나뿐인 연산자를 말하며, 여기에는 부호 연산자 ( +, - ), 증감연산자 ( ++, -- ) , 논리 부정 연산자 (!) , 비트 반전 연산자 (~) 가있다.

 

1. 부호 연산자 (+,-)

 

부호 연산자는 양수 및 음수를 표시하는 + , - 를 말한다. boolean 타입과 char 타입(음수가 없음)을 제외한 나머지 기본타입에 사용할 수 있다.

+, - 는 산술 연산자 이기도 하고, 부호 연산자 이기도 하다. 부호 연산자로 쓰일 때에는 하나의 피연산자만 필요하다. 일반적으로 부호 연산자를 다음과 같이 정수 및 실수 리터럴 앞에 붙여 양수 및 음수를 표현한다.

-------------------------------------------------------------------

int i1 = +100;

int i2 = -100;

double d1 = +3.14;

double d2 = -10.5;

--------------------------------------------------------------------

 

부호 연산자를 정수 또는 실수 타입 변수 앞에 붙일 수도 있다. 이 경우는 변수를 양수 및 음수로 표현한 것이 아니고, 변수 값의 부호를 유지하거나 바꾸기 위해 사용된다. + 연산자는 변수 값의 부호를 유지하고, -연산자는 변수 값의 부호를 양수는 음수로, 음수는 양수로 바꾼다. 다음 코드를 보면 result1 에는 x 값인 음수 -100이 그대로 저장된다. 그러나 result2 는 부호가 변경된 양수 100이 저장된다.

--------------------------------------------------------------

int x = -100;

int result1 = +x;

int result2 = -x;

--------------------------------------------------------------

부호 연산자를 사용할 때 주의할 점은 부호 연산자의 산출 타입은 int 타입이 된다는 것이다. 예를 들어 short 타입 값을 부호 연산하면 int 타입 값으로 바뀐다. 그래서 다음 코드는 컴파일 에러가 발생한다.

-------------------------------------------------

short s = 100;

short result = -s;     //컴파일 에러

-------------------------------------------------

그렇기 때문에 다음과 같이 변경되어야 한다.

-------------------------------------------------

short s = 100;

int result = -s;

-------------------------------------------------

 

---------------------------[ SignOperatorExample.java ] 부호 연산자 ------------------------------

public class SignOperatorExample {

public static void main(String[] args) {

int x = -100;

int result1 = +x;

int result2 = -x;

System.out.println("result1=" + result1);

System.out.println("result2=" + result2);

 

short s = 100;

//short result3 = -s;  //컴파일 에러 

int result3 = -s; 

System.out.println("result3=" + result3);

 

}

}

---------------------------------------------------------------------------------------------------------

Console

result1=-100

result2=100

result3=-100

---------------------------------------------------------------------------------------------------------
 
 
 
 
2. 증감 연산자 (++, -- )
 
증감 연산자는 변수의 값을 1 증가 (++) 시키거나 1 감소 (--) 시키는 연산자를 말한다. boolean 타입을 제외한 모든 기본타입의 피연산자에 사용할 수 있다.
++연산자는 피연산자의 기존 값에 1을 더해서 그 결과를 다시 피연산자에 저장한다. 예를들어 num변수의 기존 값이 5 라면 ++num 연산 후 num 변수의 값은 6 이 된다. 그래서 ++ 연산자를 증가 연산자라고 부른다. -- 연산자는 피연산자의 기존 값에 1을 뺀 후 그 결과를 다시 피연산자에 저장한다. 예를들어 num 변수의 가존 값이 5 라면 --num 연산 후 num 변수의 값은 4 가 된다. 그래서 -- 연산자를 감소 연산자라고 부른다. 증가 연산자와 감소 연산자는 변수의 앞뒤 어디에든 올 수 있다. 연산식에서 증감 연산자만 있는 경우에는 증감 연산자가 변수 앞 또는 뒤 어디든 위치해도 상관 없다.
 
--------------------------------------------------------------------------------------------
++i;                                                            --i;
i++;       모두 i=i+1; 로 동일                              i--;          모두 i=i-1; 로 동일    
--------------------------------------------------------------------------------------------
 

하지만 다른 연산자와 함께 사용하는 연산식에서는 증감 연산자의 위치에 따라 연산식의 결과가 다르게 나오므로 주의해야한다. 증감 연산자가 변수 앞에 있으면 우선 변수를 1 증가 또는 1 감소시킨 후에 다른 연산자와 계산한다. 증감 연산자가 변수 뒤에 있으면 다른 연산자를 먼저 처리한 후 변수를 1 증가 또는 1 감소시킨다. 예를 들어 다음 코드를 보자.

 

---------------------------------------------------------------

int x = 1;

int y = 1;

int result1 = ++x + 10;

int result2 = y++ + 10;

--------------------------------------------------------------------

 

변수 result1 에는 12가 저장된다. 그 이유는 x 의 값이1 증가되어 2가 된 후 10과 합해진것이고 result2 에는 11이 저장되는데 그 이유는 y의값인 1과 10이 합해서 11이되고 그후에 y가 2가되어 저장된다.

 

-----------------------------------------------------------------------[ IncreaseDecreaseOperatorExample.java ] 증감 연산자------------------------------------

public class IncreaseDecreaseOperatorExample {

public static void main(String[] args) {

int x = 10;

int y = 10;

int z;

 

System.out.println("-----------------------");

x++;

++x;

System.out.println("x=" + x);

 

System.out.println("-----------------------");

y--;

--y;

System.out.println("y=" + y);

 

System.out.println("-----------------------");

z = x++;

System.out.println("z=" + z);

System.out.println("x=" + x);

 

System.out.println("-----------------------");

z = ++x;

System.out.println("z=" + z);

System.out.println("x=" + x);

 

System.out.println("-----------------------");

z = ++x + y++;

System.out.println("z=" + z);

System.out.println("x=" + x);

System.out.println("y=" + y);

}

}

------------------------------------------------------------------------------------------------------------------------------------------------

Console

-----------------------

x=12

-----------------------

y=8

-----------------------

z=12

x=13

-----------------------

z=14

x=14

-----------------------

z=23

x=15

y=9

-------------------------------------------------------------------------------------------------------------------------------------------------
 
많은 사람들이 ++i 가 i=i+1보다 연산속도가 빠르다고 알고 있는데, i=i+1은 = 연산자와 +연산자가 있기 떄문에 두번의 연산이 필요하지만 ++는 하나의 연산만 수행하기 떄문이라고 한다. 하지만 ++i와 i=i+1 은 실제로 컴파일 하면 동일한 바이트 코드가 생성된다. 그렇기 때문에 둘 중 어떤것이 연산속도가 빠르다고 볼 수는 없다. 이클립스는 컴파일된 바이트 코드도 확인이 가능한데, Package Explorer 뷰에서는 소스파일(.java) 이 저장된 sec 폴더만 보이기 때문에 바이트코드파일 (.class) 이 저장된 bin 폴더를 볼 수 없다. bin 폴더를 보려면 Navigator 뷰를 추가하면 된다. 메뉴에서 [ Window - Show View - Navigator ] 를 선택하면 퍼스펙티브에 추가된다. Navigator 뷰에서 bin 폴더의 바이트 코드 파일을열어보면 컴파일된 내용을 확인할 수 있다. 본론으로 돌아가서 ++i와 i=i+1 을 작성해서 생성된 바이트 코드를 비교해보면 다음과 같이 동일한 것을 알수 있다.
----------------------------------------------------------------------------
소스             int i = 0; ++i;                        int i = 0; i=i+1;
 
바이트          iconst_0                                     iconst_0
                   istore_1 [i]                                  istore_1 [i]
                   ilnc 1 1 [i]                                  ilnc 1 1 [i]
-------------------------------------------------------------------------------------------
 
 
 
 
 
3. 논리 부정 연산자(!)
 
논리 부정 연산자는 ture를 false로, false를 ture로 변경하기 때문에 boolean타입에만 사용 가능하다.
논리부정 연산자는 조건문과 제어문에서 사용되어 조건식의 값을 부정하도록 해서 ㅅㄹ행 흐름을 제어할 때 주로 사용된다. 또한 두 가지 상태(ture,false)를 번갈아 가면서 변경하는 토글 (toggle) 기능을 구현할 때도 주로 사용한다.

 

----------------------------------------------------------------[ DenyLogicOperatorExample.java ] 논리 부정 연산자 -------------------------
public class DenyLogicOperatorExample {
public static void main(String[] args) {
boolean play = true;
    System.out.println(play);
 
    play = !play;
    System.out.println(play);
 
    play = !play;
    System.out.println(play);
}
}
---------------------------------------------------------------------------------------------------------------------------------
Console
true
false
true
--------------------------------------------------------------------------------------------------------------------------------
 
 
 
 

 

 

4. 비트 반전 연산자 (~)

 

비트 반전 연산자는 정수 타입 (byte, short, int, long ) 의 피연산자에만 사용되며, 피연산자를 2 진수로 표현했을 때 비트값인 0을 1로, 1은 0 으로 반전한다. 연산 후, 부호 비트인 최상위 비트를 포함해서 모든 비트가 반전되기 때문에, 부호가 반대인 새로운 값이 산출된다.

비트 반전 연산자를 사용할때의 주의점은 비트 반전 연산자 산출 타입은 int 타입이 된다는 것이다. 피연산자는 연산을 수행하기 전에 int 타입으로 변환되고, 비트 반전이 일어난다. 그래서 다음 코드는 컴파일 에러가 발생한다.

 

----------------------------------

byte v1 = 10;

byte v2 = ~v1;     //컴파일 에러

----------------------------------

 

그렇기 때문에 다음과 같이 변경을하면

----------------------------------

byte v1 = 10;

int v2 = ~v1;     

----------------------------------

 

비트 반전 연산자의 결과를 이용하면 부호가 반대인 정수를 구할 수도 있다. 물론 간단하게 부호 연산자인 - 를 이용해도 되겠지만, 비트 반전 연산자의 산출값에 1을 더하기하면 부호가 반대인 정수를 얻을 수 있다. 10 을 비트반전하면 -11을 얻는데, 여기에 1을 더하면 -10 을 얻는다.

-------------------------------------------

byte v1 = 10;

byte v2 = ~v1 +1;      //-10 이 v2에 저장

----------------------------------

 

자바는 정수값을 총 32비트의 이진 문자열로 리턴하는 Integer.toBinaryString() 메소드를 제공한다.

----------------------------------------------------------------------

String v1BinaryString - Integer.toBinaryString(10);

---------------------------------------------------------------------

Integer.toBinaryString() 메소드는 앞의 비트가 모두 0이면 0은 생략되고 나머지 문자열만 리턴하기 때문에 총 32 개의 문자열을 모두 얻기 위해서는 다음과 같은 메소드가 필요하다. 리턴하는 str의 문자 수를 조사해서 32 보다 작으면 앞에 0 을 붙이도록 한 것 이다.

-------------------------------------------------------------------------------

public static String toBinaryString(int value) {

String str = Integer.toBinaryString(value);

while(str.length() < 32 ) {

str = "0" + str ;

}

return str ;

}

-----------------------------------------------------------------------------

toBinaryString() 메소드의 전체 코드는 학습하다보면 차츰 알게 될 것이니 지금은 toBinaryString()메소드를 이용해서 비트 반전 연산자의 산출 결과만 확인해 보자.

 

-----------------------------------[ BitReverseOperatorExample.java ] 비트반전연산자 -----------------------------------------------

public class BitReverseOperatorExample {

public static void main(String[] args) {

int v1 = 10;

int v2 = ~v1;

int v3 = ~v1 + 1;

System.out.println(toBinaryString(v1) + " (십진수: " + v1 + ")");

System.out.println(toBinaryString(v2) + " (십진수: " + v2 + ")");

System.out.println(toBinaryString(v3) + " (십진수: " + v3 + ")");

System.out.println();

 

int v4 = -10;

int v5 = ~v4;

int v6 = ~v4 + 1;

System.out.println(toBinaryString(v4) + " (십진수: " + v4 + ")");

System.out.println(toBinaryString(v5) + " (십진수: " + v5 + ")");

System.out.println(toBinaryString(v6) + " (십진수: " + v6 + ")");

}

 

public static String toBinaryString(int value) {

String str = Integer.toBinaryString(value);

while(str.length() < 32) {

str = "0" + str;

}

return str;

}

}

--------------------------------------------------------------------------------------------------------------

Console

00000000000000000000000000001010 (십진수: 10)

11111111111111111111111111110101 (십진수: -11)

11111111111111111111111111110110 (십진수: -10)

 

11111111111111111111111111110110 (십진수: -10)

00000000000000000000000000001001 (십진수: 9)

00000000000000000000000000001010 (십진수: 10)

--------------------------------------------------------------------------------------------------------------

 

 

 

 

 

 

profile

이세개발

@print(name)

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!