정리 노트/꿈날개_JAVA_기초

13. 연산자 : (개념 / 종류 / 우선 순위) + 예제

우주바다 2023. 6. 25. 21:06
728x90

 


[1]  연산자와 피연산자


 연산자(Operator) 
: 어떤 기능을 수행하는 기호 . 연산 수행의 주체.

ex) 산술연산자 , 대입연산자 등

피연산자(Operand)
: 연산자의 작업 대상. 

ex) 변수, 상수, 리터럴, 수식



[2]  연산자의 종류


연산자는 기준에 따라 다르게 분류할 수 있는데,

피연산자의 개수에 따른 분류는 아래와 같다.

1.  단항연산자 (부호, 증감, 비트전환, 논리부정)

2.  이항연산자

3.  삼항연산자(조건연산자)


1. 단항연산자 

:  피연산자가 1개인 연산자.

  부호, 증감, 비트, 논리부정

 

부호 :  + , -

양수, 음수를 표현하는 부호. 양수는 부호를 생략할 수 있다.

 

증감 연산자 : ++, --

증가 연산자 (++) : 피연산자의 값을 1 증가시킨다.
감소 연산자 (--) : 피연산자의 값을 1 감소시킨다.

증감 연산자는 전위형과 후위형으로 나뉜다.

후위형 :  i++;   // 값이 참조되기 전에 증가시킴
전위형 :  ++i;   // 값이 참조된 후 증가

int x = 10;
int y = 10;
System.out.println((x++)); // 10
System.out.println(x); 	   // 11
System.out.println(++y); // 11
System.out.println(y); // 11

 

비트 (전환)연산자 : ~

비트를 뒤집는 연산자. (0을 1로, 1을 0으로)

cpu는 감산이 불가능하고 가산, 누산만 처리할 수 있다.

이 때,  피연산자를 2진수로 표현한 후 모든 수를 뒤집고 1을 더하면 부호를 바꿀 수 있다. 

(1의 보수 개념을 이용한 비트 전환연산)

따라서 비트 전환 연산자를 1의 보수 연산자라고도 한다.

* 참고: 10진수를 2진수로 쉽게 바꾸는 법

더보기

2에  가능한 가장 큰 수로 곱하면서 우측에는 나머지를, 좌측은 2, 아래는 곱한 수를 작성.

나머지를 아래에서 우측 위로 순서대로 적으면 2진수가 된다.

------- ex) 5 는 2진수로 101

2 | 5       . . . 1 (나머지) 
    ----
2 | 2        . . . 0 
    ----
      1 

------  ex) 6은 2진수로 110

2 | 6     . . . 0 (나머지) 
    ----
2 | 3     . . . 1 
    ----
      1 

 

논리 부정 (not)연산자 : ~

boolean 값을 가지는 대상의 true/false 값을 반전시킨다.

따라서 피연산자의 자료형이 boolean일때만 사용 가능하다.

public class Operator_03 {
	public static void main(String[] args) {
		boolean power = false;
		System.out.println("power 값: " + power);
		System.out.println("power 값: " + !power);
		if(power) {
			System.out.println("전원이 켜져있습니다.");
		}else{
			System.out.println("전원이 꺼져있습니다.");
		}
	}
}

2.이항연산자
: 피연산자가 2개인 연산자.

 

이항연산자와 형 변환
이항 연산자는 연산 실행 전, 피연산자의 타입을 일치시키는 작업을 한다.
- 디폴트 타입 int보다 바이트 수가 작은 타입은 int로 자동 변환된다.
- 정수와 실수의 연산은, 표현 범위가 더 넓은 타입으로 형 변환 된다.

: byte + short   =>  int + int       =>  int
: char + int     =>  int + int       =>  int 
: int + float    =>  float + float   =>  float
: double + float =>  double + double => double

public class Default_type {
	public static void main(String[] args) {
		// 이항 연산자와 디폴트 타입
		byte b1 = 127;
		byte b2 = 1;
		float f1 = 15.5f;
		double d1 = 10.5;
		
		//byte b3 = b1 + b2;   오버플로우 에러
		// 해결 1: int 형으로 받는다 (자동 캐스팅)
		int b3 = b1 + b2; 		// 128
		// 해결 2: 강제 캐스팅  = > 데이터 손실, 루핑 
		byte b4 = (byte)(b1 + b2); 	// -128
		System.out.println(b3 + "," + b4);
		
		// 정수와 실수 => 범위가 넓은 쪽으로 연산
		float f2 = b1 + f1;   // 127 + 15.5
		double d2 = f1 + d1; // 15.5 + 10.5
		System.out.println(f2 + ", " + d2);//142.5, 26.0		
	}
}

 

이항연산자의 종류
: 산술, 대입, 비교, 논리, 비트 

 

- 산술 :  +   -   *   /   %   <<    >> 

                좌항과 우항을 산술 연산하는 연산자.

 

* 시프트 연산자 ( << , >> )

더보기

left shift operator, right shift operator.
2의 n 제곱 으로 곱하거나 나눈 결과를 반환한다.
속도가 빨라서 그래픽 분야에서 많이 사용.(복잡한 연산이 아니라 비트 위치만 이동하므로)

 

x << n   은 x * 2의 n제곱 과 같다. / 비트를 왼쪽 끝에서 n개만큼 잘라 오른쪽 끝으로 붙인다.
x >> n  은 x / 2의 n제곱 과 같다. / 비트를 오른쪽 끝에서 n개만큼 잘라 왼쪽 끝으로 붙인다.

 

- 대입 : =

            대입과 복합대입 연산자는 유일하게 우측에서 좌측으로 실행되는 연산자.

            단, 상수는 예외 (실행 불가)

- 복합대입:  +=   -=    *=   /=   %=

                    (Compound Assignment Operators)

                    변수가 포함된 산술 연산식을 해당 변수에 재할당하는 경우, 이를 간단하게 줄여쓰는 연산자.

                    값을 누적시킬 때 주로 사용된다. 

sum = sum + 1
sum += 1

- 비교 :  >  <  >=  =<  ==  !=  

              두 항의 크기를 비교하거나 동일 값 여부를 판단한다.

               피연산자를 같은 타입으로 변환한 후, 비교 실행. ( 결과는 true 또는 false가 된다.)
               ex)   A < B  =>  65 < 66   ( int로 변환) =>  true.  
                      10.0d == 10.0f    =>   10.0d  == 10.0d  (double로 변환)  => true  

 

                      boolean을 제외한) 기본형과 참조형에 사용되며, 
                      참조형 변수는 == 와 != 만 사용 가능하다. 참조형은 기본적으로 주소 비교가 실행된다.  
                      값에 대한 비교는 .equals(String)  메서드를 사용한다.  

System.out.println(true == true);   // true
System.out.println(true != false); // false
System.out.println(true > false); 
//error: bad operand types for binary operator '>'
public class Main
{
	public static void main(String[] args) {
	    String a = "사과";
	    String b = "포도";
	    String c = "사과";
	    
           System.out.println("a == b : " + a==b);
           System.out.println("a == c : " + a==c); 
           System.out.println("a != b :" + a!=b); 
           System.out.println("a.equals("사과") : " + a.equals("사과"));
           System.out.println("a.equals(c) : " + a.equals(c));
	}
}
/*
false
false
true
a.equals("사과") : true
a.equals(c) : true
*/
public class Main
{
	public static void main(String[] args) {
		// 참조형 타입의 == , != 는 리터럴의 메모리 위치주소를 비교.
		String str1 = "재미있는";
		String str2 = "자바"; // 기존에 없던 리터럴이므로 새로운 곳에 인스턴스 생성.
		String str3 = "자바"; // 힙에 같은 리터럴이 이미 있음. 따라서 주소를 공유.
		String str4 = new String("자바"); // 새로운 인스턴스 생성.
		
		boolean result = (str1 == str2);
		System.out.println(result); //false (리터럴이 다르니 주소도 다름)
		
		// (어? 이미 있는 값이네? 너도 여기를 pointing 해!)
		boolean result2 = (str2 == str3);  
		System.out.println(result2); //true (주소가 같음)
		
		boolean result3 = (str3 == str4);
		System.out.println(result3); //false (같은 리터럴이지만 다른 주소에 각각 존재)

		System.out.println(str1.equals(str2));  // false
		System.out.println(str2.equals(str3));  // true 	
	}
}

 

 

- 논리 : &&  ||     

            : 더블엔드 (&&) : 피연산자 둘 다 true 면 ture.           

            : 더블파이프: 피연산자 중 어느 한쪽이라도 true 면, true.

           : 피연산자와 연산 결과 모두 반드시 boolean type 이어야 한다.
           : &&가 ||보다 우선순위가 높다.

              따라서 함께 사용하는 경우 가독성과 편의를 위해 괄호를 사용한다.

           cf)   &와 |는 비트연산자가 선점한 문법. 2개씩 써야 논리 연산자.

(i > 3) && (i < 5)    //false.
(i > 3) || (i < 0)    //true

//  ex) x에 저장된 값이 알파벳인지 확인하는 조건
(x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z')
//    소문자             OR         대문자.


       

- 비트 연산자:   &  |   ^   

 기호 이름:   앤드 , 파이프,  캐럿

 피연산자를 비트 단위로 연산한다. 단, 실수는 제외 (정수만 계산 가능)

&   (and) 연산자 : 피연산자 둘 다 1이어야 1.
|   (or) 연산자  : 피연산자 중 한쪽이라도 1이면 1.
^   (xor) 연산자 : 피연산자가 서로 달라야 1.  (= 배타적 논리합, exclusive or)

// & , | , ^ : 비트 연산자 ( and, or, xor )
	
int x = 8;
int y = 5;
System.out.println("x를 2진수로 변환하면: " + Integer.toBinaryString(x));
System.out.println("y를 2진수로 변환하면: " + Integer.toBinaryString(y));
		
System.out.println("x & y = " + (x & y)); // 둘 다 1일 때 1.
System.out.println("x | y = " + (x | y)); // 둘 중 하나라도 1이면 1.
System.out.println("x ^ y = " + (x ^ y)); // 서로 값이 다를 때 1

/*
x를 2진수로 변환하면: 1000
y를 2진수로 변환하면: 101
x & y = 0
x | y = 13
x ^ y = 13
*/

3. 삼항 연산자 (조건 연산자)

(조건식) ? 표현식 1 : 표현식2     

: 조건식의 연산 결과가 true면, 표현식 1의 결과를 반환하고,
  false인 경우 표현식2의 결과를 반환한다. 
  (if = else문의 대체 문법. 더 간결함)

int score = 70;
char grade = (score >= 90) ? 'A' : (score >= 80 ? 'B' : 'C');  
// grade = C

 



[3] 연산자의 우선순위 


1.  괄호가 우선 순위가 가장 높다.
2.  연산자 우선 순위 : 단항 > 이항 > 삼항 > 대입
3.  이항 연산자 우선 순위: 산술 > 비교 > 논리

 

+) 참고

* 아무리 성능 좋은 cpu여도 오차는 무조건 존재한다.
* jvm 이 할당받아 이용하는 메모리 영역 

: http://www.tcpschool.com/java/java_array_memory

728x90
반응형