[17일차] 변수와 시스템 입출력 & 연산자와 연산식

2023. 1. 13. 16:32데이터 엔지니어링 과정/java

목차
1. 변수와 시스템 입출력
2. 연산자와 연산식
3. 연산자의 종류

1. 변수와 시스템 입출력

1. 모니터로 변수값 출력하기

(1) System.out.println(리터럴 또는 변수); 형태

  • System.
    ➡ 시스템이 가지고 있는
  • out.
    ➡ 출력 장치로
  • println(리터럴 또는 변수);
    ➡ 괄호 안의 내용을 출력하고 행을 바꿔라
메소드 의미
println(내용); 괄호 안의 내용을 출력하고 행을 바꿔라
print(내용); 괄호 안의 내용을 출력만 해라
printf("형식문자열", 값1, 값2, ···); 괄호 안의 첫 번째 문자열 형식대로 내용을 출력해라

(2) printf()에 자주 사용되는 형식 문자열

  • 정수
형식화된 문자열 설명 출력형태
%d 정수 123
%6d 6자리 정수. 왼쪽 빈 자리 공백 ___123
%-6d 6자리 정수. 오른쪽 빈 자리 공백 123___
%06d 6자리 정수. 왼쪽 빈 자리 0 채움 000123
  • 실수
형식화된 문자열 설명 출력형태
%10.2f 소수점 이상 7자리, 소수점 이하 2자리. 왼쪽 빈 자리 공백 ____123.45
%-10.2f 소수점 이상 7자리, 소수점 이하 2자리. 오른쪽 빈 자리 공백 123.45____
%010.2f 소수점 이상 7자리, 소수점 이하 2자리. 왼쪽 빈 자리 0 채움 0000123.45
  • 문자열
형식화된 문자열 설명 출력형태
%s 문자열 abc
%6s 6자리 문자열. 왼쪽 빈 자리 공백 ___abc
%-6s 6자리 문자열. 오른쪽 빈 자리 공백 abc___
  • 특수 문자
형식화된 문자열 설명 출력형태
\t 탭 (tab)  
\n 줄 바꿈  
%% % %
package sec04.exam01;

public class PrintExample {
	public static void main(String[] args) {
		int value = 123;
		System.out.printf("상품의 가격 :%d원\n",value);
		System.out.printf("상품의 가격 :%6d원\n",value);
		System.out.printf("상품의 가격 :%-6d원\n",value);
		System.out.printf("상품의 가격 :%06d원\n",value);
		
		double area = 3.14159 * 10 * 10 ;
		System.out.printf("반지름이 %d인 원의 넓이 : %10.2f\n", 10, area);
		
		String name = "홍길동";
		String job = "도적";
		System.out.printf("%6d : %-10s : %10s\n", 1, name, job);
	}
}

>>> 상품의 가격:123원
>>> 상품의 가격:   123원
>>> 상품의 가격:123   원
>>> 상품의 가격:000123원
>>> 반지름이 10인 원의 넓이:    314.16
>>>      1 : 홍길동        :         도적

2. 키보드에서 입력된 내용을 변수에 저장하기

(1) int keyCode = System.in.read(); 형태

  • System.
  • ➡ 시스템이 가지고 있는
  • in.
    ➡ 입력 장치에서
  • read();
    ➡ 입력된 키보드를 읽어라
package sec04.exam02;

public class KeyCodeExample {
	public static void main(String[] args) throws Exception {
		int keyCode;
		
		keyCode = System.in.read();
		System.out.println("keyCode: " + keyCode);
		
		keyCode = System.in.read();
		System.out.println("keyCode: " + keyCode);
		
		keyCode = System.in.read();
		System.out.println("keyCode: " + keyCode);
	}

}

<<< a
>>> keyCode: 97
>>> keyCode: 13
>>> keyCode: 10

👀 main() 메소드 끝에 throws Exception이 붙어 있는데, 이는 System.in.read()에 대한 예외처리 코드이다.

🐰 a 하나만 입력했는데, 출력된 값은 3개이다. 그 이유는 a에 해당하는 값인 97, enter를 쳤을 때 커서 이동을 하는 13, 밑으로 내려가는 10이 출력되기 때문이다.

(2) 입력된 키의 개수와 상관없이 키보드 읽기

package sec04.exam03;

public class ContinuekeyCodeReadExample {
	public static void main(String[] args) throws Exception {
		int keyCode;
		
		while (true) {
			keyCode = System.in.read();
			System.out.println("keyCode: "+keyCode);
		}
	}

}

<<< a
>>> keyCode: 97
>>> keyCode: 13
>>> keyCode: 10
<<< 아
>>> keyCode: 190
>>> keyCode: 198
>>> keyCode: 13
>>> keyCode: 10

while (true)를 사용해서 무한 반복이 된다. 

(3) q를 입력하여 반복 종료

package sec04.exam04;

public class QstopExample {
	public static void main(String[] args) throws Exception {
		int keyCode;
		
		while (true) {
			keyCode = System.in.read();
			System.out.println("keyCode: "+keyCode);
			if (keyCode == 113) {
				break;
			}
		}
		System.out.println("종료");
	}
}


<<< ㅎ
>>> keyCode: 164
>>> keyCode: 190
>>> keyCode: 13
>>> keyCode: 10
<<< q
>>> keyCode: 113
>>> 종료

반복이 중지되게 하려면 if문을 사용하면 된다.

(3) Scanner 클래스

System.in.read()의 단점은 2개 이상의 키가 조합된 한글을 읽을 수 없다는 점과 키보드로부터 입력된 내용을 통문자열로 읽지 못한다는 점이다.

이러한 단점을 보완하게 위해 자바는 Scanner 클래스를 제공하고 있다.

  • newScanner(System.in)
    시스템의 입력 장치로부터 읽는 Scanner를 생성하는 코드
  • scanner.nextLine() 메소드
    - 생성된 Scanner는 scanner변수에 저장했다가 키보드에서 읽고 싶을 때 사용
    - enter 키가 입력되기 전까지 대기 상태이고, enter 키가 입력되면 입력된 모든 내용을 문자열로 읽는다.
package sec04.exam05;

import java.util.Scanner;

public class ScannerExample {

	public static void main(String[] args) throws Exception {
		Scanner scanner = new Scanner(System.in);
		String inputData;
		
		while (true) {
			inputData = scanner.nextLine();
			System.out.println("입력된 문자열: \"" + inputData + "\"");
			if (inputData.equals("q")) {
				break;
			}
		}
		System.out.println("종료");
	}

}

<<< a
>>> 입력된 문자열: "a"
<<< 혼자 공부하지는 않는 자바
>>> 입력된 문자열: "혼자 공부하지는 않는 자바"
<<< q
>>> 입력된 문자열: "q"
>>> 종료

👀 자바는 문자열이 동일한지 비교할 때에는 equals() 메소드를 활용한다.

 

2. 연산자와 연산식

1. 개념

  • 연산자 : 연산에 사용되는 기호나 표시
  • 피연산자 : 연산자와 함께 연산되는 데이터
  • 연산식 : 연산자와 피연산자를 이용하여 연산의 과정을 기술한 것

2. 연산자의 종류

연산자들은 피연산자를 연산해서 값을 산출하는데, 산출되는 값의 타입(자료형)은 연산자별로 다르다.

연산자 종류 연산자 피연산자 산출값 기능
산술 +, -, *, /, % 이항 숫자 사칙연산 및 나머지 계산
부호 +, - 단항 숫자 음수와 양수의 부호
문자열 + 이항 문자열 두 문자열을 연결
대입 =, +=, -=, *=, /=, %= 이항 다양 우변의 값을 좌변의 변수에 대입
증감 ++, -- 단항 숫자 1만큼 증가/감소
비교 ==, !=, >, <, >=, <=, instanceof 이항 boolean 값의 비교
논리 !, &, |, &&, || 단항
이항
boolean 논리 부정, 논리곱, 논리합
조건 (조건식)  A : B 삼항 다양 조건식에 따라 A 또는 B 중 하나를 선택

연산자는 반드시 하나의 값을 산출해낸다.

3. 연산의 방향과 우선순위

프로그램에는 연산자의 연산 방향과 연산자 간의 우선 순위가 정해져 있다. 

(1) 연산의 방향

  • 대부분의 연산자는 왼쪽에서 오른쪽 방향으로 연산 수행
  • 단항 연산자 (++, --, ~, !), 부호 연산자(+, -), 대입 연산자(=, +=, -=, ···)는 오른쪽에서 왼쪽 방향으로 연산 수행

(2) 연산의 우선순위

① 단항, 이항, 삼항 연산자 순으로 우선순위 가짐

② 산술, 비교, 논리, 대입 연산자 순으로 우선순위 가짐

③ 복잡한 연산식에서는 괄호()를 사용하여 우선순위 지정

 

3. 연산자의 종류

1. 단항 연산자

(1) 부호 연산자 + -

변수의 부호를 유지하거나 변경한다.

boolean 타입과 char 타입을 제외한 나머지 기본 타입에 사용할 수 있다.

연산식 설명
+ 피연산자 피연산자의 부호 유지
- 피연산자 피연산자의 부호 변경
package sec02.exam01;

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);
		
		byte b = 100;
		//byte result3 = -b;
		int result3 = -b;
		System.out.println("result3=" + result3);
	}
}

>>> result1=-100
>>> result2=100
>>> result3=-100

(2) 증감 연산자 ++ --

변수의 값을 1 증가(++)시키거나 1 감소(--) 시키는 연산자이다.

boolean 타입을 제외한 모든 기본 타입의 피연산자에 사용할 수 있다.

연산식 설명
++ 피연산자 다른 연산을 수행하기 전에 피연산자의 값을 1 증가시킴
-- 피연산자 다른 연산을 수행하기 전에 피연산자의 값을 1 감소시킴
피연산자 ++ 다른 연산을 수행한 후에 피연산자의 값을 1 증가시킴
피연산자 -- 다른 연산을 숳애한 후에 피연산자의 값을 1 감소시킴
package sec02.exam02;

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);
	}

}


>>> ---------------
>>> x=12
>>> ---------------
>>> y=8
>>> ---------------
>>> z=12
>>> x=13
>>> ---------------
>>> z=14
>>> x=14
>>> ---------------
>>> z=23
>>> x=15
>>> y=9

(3) 논리 부정 연산자

true를 false로, false를 true로 변경하기 때문에, boolean 타입에만 사용할 수 있다.

연산식 설명
! 피연산자 피연산자가 true면 false 값을 산출
피연산자가 fasle면 true 값을 산출
package sec02.exam03;

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);
	}
}

>>> true
>>> false
>>> true

2. 이항 연산자

(1) 산술 연산자 + - * / %

  • boolean 타입을 제외한 모든 기본 타입에서 사용 가능
연산식 설명
피연산자 + 피연산자 덧셈 연산
피연산자 - 피연산자 뺄셈 연산
피연산자 * 피연산자 곱셈 연산
피연산자 / 피연산자 왼쪽 피연산자를 오른쪽 피연산자로 나눗셈 연산
피연산자 % 피연산자 왼쪽 피연산자를 오른쪽 피연산자로 나눈 나머지를 구하는 연산
  • 피연산자들의 타입이 동일하지 않은 경우, 규칙을 통해 피연산자들의 타입을 일치시킨 후, 연산을 수행한다.
    ① 피연산자들이 byte, short, char 타입일 경우 모두 int 타입으로 변환한 후에 연산 수행
    ② 피연산자들이 모두 정수 타입이고 long 타입이 포함되어 있을 경우, 모두 long 타입으로 변환된 후 연산 수행
    ③ 피연산자 중 실수 타입(float, double)이 있을 경우, 허용 범위가 큰 실수 타입으로 변환된 후 연산 수행
package sec02.exam04;

public class ArithmeticOperatorExample {
	public static void main(String[] args) {
		int v1 = 5;
		int v2 = 2;
		
		int result1= v1 + v2;
		System.out.println("result1="+result1);
		
		int result2= v1 -v2;
		System.out.println("result2=" + result2);
		
		int result3 = v1*v2;
		System.out.println("result3="+ result3);
		
		int result4 = v1/v2;
		System.out.println("result4="+ result4);
		
		int result5 = v1%v2;
		System.out.println("result5="+ result5);
		
		double result6 = (double) v1/v2;
		System.out.println("result6="+ result6);
	}
}

>>> result1=7
>>> result2=3
>>> result3=10
>>> result4=2
>>> result5=1
>>> result6=2.5
  • char 타입도 정수 타입이므로 산술 연산이 가능하다. 
    int 타입으로 변환되므로, 연산 결과는 int 타입이 된다.

(2) 문자열 결합 연산자 +

문자열을 서로 결합하는 연산자이다. 

문자열과 숫자가 혼합된 + 연산식에서는 왼쪽부터 오른쪽으로 연산을 진행하면 된다.

package sec02.exam06;

public class StringConcatExample {
	public static void main(String[] args) {
		String str1 = "JDK" + 6.0;
		String str2 = str1 + "특징" ;
		System.out.println(str2);
		
		String str3 = "JDK" + 3 + 3.0;
		String str4 = 3 + 3.0 + "JDK";
		System.out.println(str3);
		System.out.println(str4);
	}
}

>>> JDK6.0특징
>>> JDK33.0
>>> 6.0JDK

(3) 비교 연산자 < <= > >= == !=

피연산자의 대소 또는 동등을 비교해서 true, false를 산출한다.

흐름 제어문인 조건문(if), 반복문(for, while)에서 주로 이용되어 실행 흐름을 제어할 때 사용된다.

대소 연산자는 boolean을 제외한 기본 타입에 사용할 수 있고, 동등 연산자는 모든 타입에 사용할 수 있다.

구분 연산식 설명
동등
비교
피연산자1 == 피연산자2 두 피연산자의 값이 같은지를 검사
피연산자1 != 피연산자2 두 피연산자의 값이 다른지를 검사
크기
비교
피연산자1 > 피연산자2 피연산자1이 큰지를 검사
피연산자1 >= 피연산자2 피연산자1이 크거나 같은지를 검사
피연산자1 < 피연산자2 피연산자1이 작은지를 검사
피연산자1 <= 피연산자2 피연산자 1이 작거나 같은지를 검사

👀 만약 피연산자가 char 타입이라면, 유니코드 값으로 비교 연산을 수행한다.

package sec02.exam07;

public class CompareOperatiorExample1 {
	public static void main(String[] args) {
		int num1 = 10;
		int num2 = 10;
		
		boolean result1 = (num1 == num2);
		boolean result2 = (num1 != num2);
		boolean result3 = (num1 <= num2);
		System.out.println("result1=" + result1);
		System.out.println("result2=" + result2);
		System.out.println("result3=" + result3);
		
		char char1 = 'A';
		char char2 = 'B';
		boolean result4 = (char1 < char2);
		System.out.println("result4= "+result4);
	}
}

>>> result1=true
>>> result2=false
>>> result3=true
>>> result4= true
  • 비교 연산자의 실수 비교
package sec02.exam08;

public class CompareOperatorExample2 {
	public static void main(String[] args) {
		int v2 = 1;
		double v3 = 1.0;
		System.out.println(v2 == v3);
		
		double v4 = 0.1;
		float v5 = 0.1f;
		System.out.println(v4 == v5);
		System.out.println((float)v4 == v5);
		System.out.println((int)(v4*10) == (int)(v5*10)); 
	}
}

>>> true
>>> false
>>> true
>>> true

👀 실수의 저장 방식이 부동 소수점 방식이 0.1을 정확히 표현할 수 없기에 예외가 발생한다. 해결책은 피연산자들 모두 float 타입으로 변환해서 비교하거나 정수 타입으로 변환해서 비교하는 것이다.

(4) 논리 연산자 && || & | ^ !

논리 연산자의 피연산자는 boolean 타입만 사용이 가능하다.

  • AND 논리곱
구분 연산식 결과 설명
AND
(논리곱)
true &&
또는
&
true true 피연산자 모두가 true일 경우에만 연산 결과가 true
true false false
false true false
false false false
  • OR 논리합
구분 연산식 결과 설명
OR
(논리합)
true ||
또는
|
true true 피연산자 중 하나만 true이면
연산 결과는 true
true false true
false true true
false false false
  • XOR 배타적 논리합
구분 연산식 결과 설명
XOR
(배타적 논리합)
true ^ true flase 피연산자가 하나는 true이고
다른 하나가 false일 경우에만
연산 결과가 true
true false true
false true true
false false false
  • NOT 논리 부정
구분 연산식 결과 설명
NOT
(논리 부정)
  ! true false 피연산자의 논리값을 바꿈
  false ture

🐰 &&와 &의 결과는 같다. 하지만 연산과정의 차이가 효율성의 차이를 불러온다. &&의 경우에는, 앞의 피연산자가 false라면 뒤의 연산자를 고려하지 않고 false로 산출 결과를 낸다. 하지만 &는 모든 피연산자들을 고려한 후 산출 결과를 내기 때문에 동작의 효율성에서 차이를 보인다.

package sec02.exam09;

public class LogicOperatorExample {
	public static void main(String[] args) {
		int charCode = 'A';
		
		if ((charCode >= 65) & (charCode<=90)) {
			System.out.println("대문자군요.");
		}
		
		if ((charCode >= 97) & (charCode<=122)) {
			System.out.println("소문자군요.");
		}
		
		if ( !(charCode <48) && !(charCode>57)) {
			System.out.println("0~9 숫자군요");
		}
		
		int value = 6;
		
		if ((value%2==0) | (value%3==0)) {
			System.out.println("2 또는 3의 배수군요");
		}
		
		if ((value%2==0) || (value%3==0)) {
			System.out.println("2 또는 3의 배수군요");
		}
	}
}

>>> 대문자군요.
>>> 2 또는 3의 배수군요
>>> 2 또는 3의 배수군요

(5) 대입 연산자 = += -= *= /= %=

오른쪽 피연산자의 값을 왼쪽 피연산자인 변수에 저장한다.

구분 연산식 설명
단순 대입 연산자 변수 = 피연산자 오른쪽의 피연산자의 값을 왼쪽 변수에 저장
복합 대입 연산자 변수 += 피연산자 변수 = 변수 + 피연산자와 동일
변수 -= 피연산자 변수 = 변수 - 피연산자와 동일
변수 *= 피연산자 변수 = 변수 * 피연산자와 동일
변수 /= 피연산자 변수 = 변수 / 피연산자와 동일
변수 %= 피연산자 변수 = 변수 % 피연산자와 동일
변수 &= 피연산자 변수 = 변수 & 피연산자와 동일
변수 |= 피연산자 변수 = 변수 | 피연산자와 동일
변수 ^= 피연산자 변수 = 변수 +^피연산자와 동일
package sec02.exam10;

public class AssingmentOperatorExample {
	public static void main(String[] args) {
		int result = 0;
		result += 10;
		System.out.println("result=" + result);
		result -= 5;
		System.out.println("result=" + result);
		result *=3;
		System.out.println("result=" + result);
		result/=5;
		System.out.println("result=" + result);
		result %= 3;
		System.out.print("result=" + result);
	}
}

>>> result=10
>>> result=5
>>> result=15
>>> result=3
>>> result=0

3. 삼항 연산자 

3개의 피연산자를 필요로 하는 연산자를 말한다.

? 앞의 조건식에 따라 콜론(:) 앞뒤의 피연산자가 선택된다고 해서 조건 연산식이라고도 불린다.

package sec02.exam11;

public class ConditionalOperationExample {
	public static void main(String[] args) {
		int score = 85;
		char grade = (score > 90) ? 'A' : ((score > 80) ? 'B':'C');
		System.out.println(score + "점은 " + grade + "등급입니다.");
	}
}

>>> 85점은 B등급입니다.