simDev1234
심플하고 차분하게
simDev1234
전체 방문자
오늘
어제
  • 분류 전체보기
    • Computer Science
      • Basic Math
      • Data Structure
      • Algorithm
      • Database
      • OS
    • Language
      • Java
      • Kotlin
      • SQL
    • Framework
      • Spring
      • Orm&Mapper
      • 프로젝트로 스프링 이해하기
      • 스프링 라이브러리
    • Infra
      • Cloud
      • Docker
      • Redis
      • AWS, Azure
      • Device
    • Etc
      • CleanCoding
    • Git,Github

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 404
  • null
  • scanner #next() #nextLine()
  • 스프링
  • 자바프로그래밍
  • JVM메모리구조
  • 참조변수
  • 컨트롤러
  • controllerTest
  • 자바프로그램
  • 자바메모리구조
  • 자바
  • 참조타입

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
simDev1234

심플하고 차분하게

Language/Java

[자바_복습] 연산자 구체적으로 보기

2022. 3. 7. 11:12

국비지원수업에서 배운 연산자에 대해서 이론적인 부분을 복습해보았다..

 

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

 

[연산자의 종류]

- 연산을 할 때는 1) 우선순위, 2)자료형을 고려해야 한다. 

우선순위 단항연산자   연산순서
높음 최우선 연산자 (괄호)  
↓ 단항연산자 ~, !, ++, --, (cast), -(부호) <--
산술연산자 + , - , * , /(몫) , %(나머지) -->
쉬프트 연산자
(=2진 연산자)
>>, <<, >>> -->
관계 연산자 >, >=, <, <=, ==, != -->
이진논리연산자 &, ^, |,  >> -->
일반논리연산자 &&(AND), ||(OR) -->
삼항연산자 (조건) ? 값(참) : 값(거짓) <--
대입연산자 =  
낮음 (복합 대입 연산자) +=, -=, *=, /=, %=, &=, ^=, |=, >>=, <<= <--

 

1. 단항 연산자 : ~, !, ++, --, (cast), -(부호)

> 단항의 앞에 사용하는 연산자이다.

 

(1) ~ (tilde) : 이진 논리 Not 연산자 (1의 보수)

//Tilde ~ : 2진수로 표현했을 때의 1의 보수

class Tilde{
	public static void main(String[] args){
    	int n = 10; 
		System.out.printf("[%32s]\n",Integer.toBinaryString(n));
		System.out.printf("[%32s]\n",Integer.toBinaryString(~n));
    }
}

>> 결과

[                            1010]
[11111111111111111111111111110101]

 

(2) ! : 일반논리 Not연산자

class NotOperator{
	public static void main(String[] args){
    	boolean bOk = !(3>2); //boolean bOk = !3>2; 는 불가 why? 일반논리일 경우에만 !사용 가능
		                      //(3>2) == true
		System.out.printf("!(3>2) : %b\n",bOk);
		System.out.printf("!true : %b\n",!true);
    }
}

 

>> 결과

!(3>2) : false
!true : false

 

(3) ++(증가), --(감소) : 증감 연산자

- 전위형 : ++n --> 산술연산, 명령이 있기 전에 먼저 변수값을 +1한다. (먼저 변수값을 +1)

- 후위형 : n++ --> 산술연산, 명령이 있은 후에 변수값을 +1한다. (마지막에 변수값을 +1)

public class PlusplusOperator {

	public static void main(String[] args) {
		int x = 1;
        int y = 2;
        int z;
        
        z = ++x + y++;
        System.out.printf("x : %d, y : %d, z : %d\n",x,y,z);
	}

}

>> 결과

x : 2, y : 3, z : 4

//z = ++x + y++; 의 연산 순서   
//1) ++x                 --- > x = x + 1;  //2
//2) x + y               --- > 2 + 2
//3) z = x + y           --- > z = 4;
//4) y++                 --- > y = y + 1;  //3

 

(4) -(부호) : (-1)을 곱해주는 연산자

 

(5) 강제 형변환 연산자 : cast 연산자

Casting

1. 자동 형변환 
   1) 연산시 : 자료형이 큰 쪽으로 자동 형변환
   2) 대입시 : '='를 기준으로 좌변항이 더 큰 자료형일 경우 좌변형의 자료형으로 자동 형변환

2. 강제 형변환 : '(자료형) 변수' 형식

**자동 형변환시, 프로모션(큰쪽으로 형변환)된다.
**강제 형변환시, 디모션(작은쪽으로 형변환)이 가능하나, 오버플로우의 가능성을 염두해야한다.

 

2. 산술연산자 : 사칙연산

- 사칙연산 시, 위의 Casting 방식에 따라 자동 형변환이 이루어짐.

** int보다 작은 정수형 자료형의 경우, 사칙연산 시 결과가 int형으로 나타남

  ex. byte + byte = int 

  why? 중앙처리장치 안의 연산기(ALU)를 통해 연산이 이루어지는데, 계산 시 4byte단위로 결과를 냄 

  ---> 결과적으로 int 타입으로 변환

 

3. 쉬프트연산자(=2진 연산자) : 2진수로 표현한 값에서 >>우측으로 가고, <<좌측으로 가기

- >> : 우측으로 가고, 앞쪽을 부호로 채우기

- << : 좌측으로 가고, 뒤쪽을 0으로 채우기

- >>> : 우측으로 가고, 앞쪽을 0으로 채우기

 

4. 관계연산자 : >, >=, <, <=, ==, !=

 

5. 이진논리연산자 

package mymain;

public class _05_이진논리연산자 {

	public static void main(String[] args) {
		//5. 이진논리연산자
		System.out.printf("[%32s]\n",Integer.toBinaryString(7));
		System.out.printf("[%32s]\n",Integer.toBinaryString(5));
		
		System.out.printf("[%32s]\n",Integer.toBinaryString(7&5));
		System.out.printf("[%32s]\n",Integer.toBinaryString(7|5));
		System.out.printf("[%32s]\n",Integer.toBinaryString(7^5));
		
		// & ^ | >>의 활용 사례
		
		int birthday = 0x19880815; //실제로 birthday일케 안씀... 4bit가 8개.. 32bit --> int 형
		
		System.out.printf("생년월일 : %x\n",birthday); // 19880805 '0805'제외 하고자함
		
		  //출생년도 추출
		int year = birthday >>> 16; // 16bit만큼 밀기 (16진수 하나당 4bit * 4), 앞 공간(부호영역) 양음수 상관없이 0으로 채워짐
		System.out.printf("출생년도 : %x년\n",year);
		
		  //출생월 추출
		             //0x00198808               
		int month = birthday >>> 8 & 0x000000ff;   //소거(0일때 거짓, 1일때 참. 0&0=0. 1&1=1 >> 1이 있는 쪽은 살아남)
		System.out.printf("출생월 : %02x월\n",month);
		
		  //출생일 추출
		int day = birthday & 0xff;
		//int day = birthday & 0x000000ff; 
		System.out.printf("출생월 : %02x일\n",day);
		
		  //출생연월도에서 월을 수정 - 기존 : 0x19980815
		  //1. 월의 자리를 소거 (^)  -- ^은 서로 배타적일 때 참(1), 그렇지 않으면 거짓(0) >> 1010과 1010은 같음 --> 0000이 됨
		birthday = birthday ^ 0x0000800;
		System.out.printf("생년월일 : %x\n",birthday);
		
		  //2. 추가하고 싶은 월 값 추가 (현재 : 0x19880015)   0 : 0000   5 : 0101
		  //                    |       0x00001100    1 : 0001   0 : 0000
		  //                                              0001       0101
		birthday = birthday | 0x00001100; // |는 추가(0 또는 1 = 1 >> 1010 또는 1001은 1011) 
		System.out.printf("생년월일 : %x\n",birthday);
	}

}

>> 결과

[                             111]
[                             101]
[                             101]
[                             111]
[                              10]
생년월일 : 19880815
출생년도 : 1988년
출생월 : 08월
출생월 : 15일
생년월일 : 19880015
생년월일 : 19881115

 

6. 일반논리연산자 : &&(AND), ||(OR)

- 일반논리연산자는 경제적 연산을 한다.

▼ 아래를 보면 경제적 연산을 하기 때문에 dead code 발생

class AndOr{
	public staitc void main(String[] args){
        System.out.println("----[&&]----");
        System.out.printf("true && true : %b\n", (true && true));
        System.out.printf("true && true : %b\n", (true && false));
        System.out.printf("true && true : %b\n", (false && true)); //Alert : Dead Code 
        System.out.printf("true && true : %b\n", (false && false));//Alert : Dead Code 

        System.out.println("----[||]----");
        System.out.printf("true || true : %b\n", (true || true));  //Alert : Dead Code  
        System.out.printf("true || true : %b\n", (true || false)); //Alert : Dead Code 
        System.out.printf("true || true : %b\n", (false || true));  
        System.out.printf("true || true : %b\n", (false || false));
    }
}

- 일반논리연산자 예제 ) 윤년/평년 구하기

package mymain;

import java.util.Scanner;

public class _08_일반논리연산자응용2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner = new Scanner(System.in);
		
		int year;
		System.out.print("연도 : ");
		year = scanner.nextInt();
		
		//윤년/평년
		//윤년 조건
		//조건1. 400의 배수가 되는 해 (ex.400년, 800년...2000년)
		//또는
		//조건2. 4의 배수이면서 100의 배수가 아닌 해 
		
		if((/*조건 1*/year%400==0) || (/*조건2*/year%4==0 && year%100!=0)) {
			System.out.printf("[%d]년도는 [윤년]입니다.\n",year);
		}else {
			System.out.printf("[%d]년도는 [평년]입니다.\n",year);
		}
		
		scanner.close();
	}

}

>> 결과

연도 : 2022
[2022]년도는 [평년]입니다.

 

7. 삼항 연산자 : (조건) ? 값(참) : 값(거짓)

class threeOperator{
	public static void main(String[] args){
    	int x = 10;
        int y = 4;
        String z;
        
        z = (x % y ==0)? "맞다" : "아니다";
        
        System.out.printf("%d는 %d의 배수가 %s", x, y, z);
    }
}

>> 결과

10는 4의 배수가 아니다

 

8. 대입 연산자 : =

 

9. 복합 대입 연산자 : +=, -=, *=, /=, %=, &=, ^=, |=, >>=, <<=

int n;
n = 10;
		
n++; // n = n + 1;
n+=2; // n = n + 2;
n-=3; // n = n - 3;

 

 

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

 

[연산자를 활용한 코드 예시]

 

1. 지폐/동전 갯수 세는 코드 

- 산술연산자 /와 %를 활용했을 때에 계산이 간편해짐을 볼 수 있다.

package mymain;

import java.util.Scanner;

public class MoneyCnt {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner = new Scanner(System.in);
		int input;
		int tmp;
		int[] moneyArr = {50000, 10000, 5000, 1000, 500, 100, 50, 10}; 
		int[] cntArr = new int[9];
		
		//사용자에게 금액 받기
		System.out.print("금액 : ");
		input = tmp = scanner.nextInt();
		
		//화폐 갯수 세기 : 5만권부터 /와 % 연산자로 갯수 세기
		for(int i = 0; i < moneyArr.length; i++) {
			cntArr[i] = tmp / moneyArr[i];
			tmp = tmp % moneyArr[i];
		}
		
		System.out.printf("---%d(원)에 대한 권종별 갯수---\n",input);
		System.out.printf("50000원 : %d(매)\n",cntArr[0]);
		System.out.printf("10000원 : %d(매)\n",cntArr[1]);
		System.out.printf(" 5000원 : %d(매)\n",cntArr[2]);
		System.out.printf(" 1000원 : %d(매)\n",cntArr[3]);
		System.out.printf("  500원 : %d(개)\n",cntArr[4]);
		System.out.printf("  100원 : %d(개)\n",cntArr[5]);
		System.out.printf("   50원 : %d(개)\n",cntArr[6]);
		System.out.printf("   10원 : %d(개)\n",cntArr[7]);
		System.out.printf("    1원 : %d(개)\n",cntArr[8]);
		
		scanner.close();
	}

}

 

>> 결과

금액 : 258439
---258439(원)에 대한 권종별 갯수---
50000원 : 5(매)
10000원 : 0(매)
 5000원 : 1(매)
 1000원 : 3(매)
  500원 : 0(개)
  100원 : 4(개)
   50원 : 0(개)
   10원 : 3(개)
    1원 : 0(개)

 

2. 섭씨를 화씨로, 화씨를 섭씨로 변환하기 

- 연산자를 사용할 때에 1) 연산 우선순위와 2) 자료형을 고려해야하는 이유를 볼 수 있다.

**잘못된 연산 순서와, 잘못된 자료형의 사용은 잘못된 결과를 나오게 함.

public class FarenCel {

	public static void main(String[] args) {
		// 온도변환
		// 섭씨 -> 화씨 : F = 9/5 * C + 32;
		// 화씨 -> 섭씨 : C = 5/9 *(F-32);
		
		double cel = 7.0;
		double far = 44.6;
		FarenCel.toFar(cel);
		FarenCel.toCel(far);	
	}
	static void toFar(double cel) {
		double result = (cel * 5/9) + 32;
		            //= (double *(int/int)) + int;
		            //= (double * double) + int;
		            //= double + int;
		System.out.printf("섭씨 [%.1f] = 화씨 [%.1f]\n", cel, result);
	}
	static void toCel(double far) {
		double result = (far - 32) * 5/9;
		System.out.printf("화씨 [%.1f] = 섭씨 [%.1f]\n", far, result);
	}
}

>> 결과

섭씨 [7.0] = 화씨 [35.9]
화씨 [44.6] = 섭씨 [7.0]

 

'Language > Java' 카테고리의 다른 글

[자바_복습] 중첩for문 활용_구구단/행렬/별찍기  (0) 2022.03.11
[자바_복습] 제어문 예시 - 조건문과 반복문 각각  (0) 2022.03.08
[자바_복습] Scanner 입력 메서드 구분  (0) 2022.03.04
[자바의 정석_복습] 객체지향 프로그래밍1(2) - 클래스(생성자, 초기화블럭)  (0) 2022.02.27
[자바의 정석_복습] 객체지향 프로그래밍1 - 클래스(변수,메서드)  (0) 2022.02.24
    'Language/Java' 카테고리의 다른 글
    • [자바_복습] 중첩for문 활용_구구단/행렬/별찍기
    • [자바_복습] 제어문 예시 - 조건문과 반복문 각각
    • [자바_복습] Scanner 입력 메서드 구분
    • [자바의 정석_복습] 객체지향 프로그래밍1(2) - 클래스(생성자, 초기화블럭)
    simDev1234
    simDev1234
    TIL용 블로그. * 저작권 이슈가 있는 부분이 있다면 댓글 부탁드립니다.

    티스토리툴바