1. 연산자의 우선순위

 우선순위를 알기에 앞서 연산자의 역할은 무엇이고 어떠한 것들이 있는지 알아보도록 하겠습니다. 연산자라는 것은 쉽게 말해 연산을 수행하는 기호입니다. 대표적인 사칙연산을 포함하여 컴퓨터 연산에서만 사용하는 비트 연산자(쉬프트 연산자), 상함 연산자 등이 있습니다. 그렇다면 자세하게 어떤 연산자들이 있는지 알아보도록 하겠습니다.

 

 - 최우선 연산자 : '.', [], ()

 - 단항 연산자 : !, ~, +, -, ++, --, (cast)

 - 산술 연산자 : +, -, *, /, %

 - 시프트 연산자 : <<, >>, >>>

 - 관계 연산자(비교, 항등) : >, <, >=, <=, ==, !=

 - 비트 연산자 : &, |, &&, ||

 - 삼항 연산자 : 조건항?항1:항2

 - 배정 대입 연산자 : =, +=, -=, *=, /=, %=, <<=, >>=, ^=, &=, |=

 - 후위형 증감 연산자 : ++, --

 - 순차 연산자 : ','

 

 위와 같은 연산자들이 있습니다. 우선순위는 위에서부터 아래로의 순서입니다. ( 최우선 연산자->후위형 ) 그렇다면 이제 각 연산자들이 어떠한 역할을 하는지 알아보도록 하겠습니다.

 

2. 최우선 연산자

 최우선 연산자는 말 그대로 가장 우선적으로 처리하는 연산자입니다. 우선 첫번째인 점('.')을 알아보도록 하겠습니다. 정확한 이름은 참조 연산자로써 각 클래스 내에서 사용하는 멤버나 또 다른 클래스를 참조하기 위해 사용합니다. 예시는 아래와 같습니다.

 

 - System.out.println(); // 이 문장에서 '.'은 모두 참조연산자

 

 이러한 형태는 코드를 작성할 때에나 시작할때 'import java.io.*;'과 같이 패키지를 참조할 때 많이 볼 수 있습니다. 그럼 다음으로 '[]'으로 넘어가도록 하겠습니다. 이 기호는 별다른 이름은 없습니다. 속칭 대괄호라고 할 수 있는 이 기호는 자료형이나 클래스와 함께 사용되며 해당 변수나 객체가 배열로 선언됨을 알리는 역할을 합니다. 하지만 이 사이에 숫자가 들어가 있다면 단순히 배열 안에서의 인덱스를 가리키게 됩니다.

 

 - String[] str = {"JAVA", "ASDF"};

   System.out.println(str[0]);  // 출력 결과는 'JAVA'

 

 위에서 첫줄은 str이라는 변수가 String형으로 선언된 배열임을 나타내지만 아래에서는 str배열의 0번째 요소를 가리키게 됩니다. 이제 마지막으로 ()을 알아보도록 하겠습니다. 속칭 소괄호는 특정 연산자들을 우선적으로 처리하도록 지시하는 역할을 합니다. 쉽게말해 일반적으로 사용되는 수학에서 같은 역할을 한다고 보시면 됩니다.

 

 - int x = 3*1+2;

   int y = 3*(1+2);   // '1+2'를 먼저 실행 후 '*3' 을 실행

 

3. 단항 연산자

 단항 연산자는 하나의 항을 연산하는 연산자를 말합니다. 그렇다면 각 단항 연산자들은 어떠한 역할을 하는지 알아보도록 하겠습니다. 우선 '!'에 대해서 알아보도록 하겠습니다. 다른 언어들과 마찬가지로 이 기호는 부정하는 역할을 수행합니다. 예시를 보도록 하겠습니다.

 

 - boolean bool = false;

   boolean bool2 = !bool;

 

 위와 같이 코드를 작성한다면 bool에는 false값이, bool2에는 bool의 반대 값인 true가 저장 될 것입니다. 이 부정을 의미하는 '!'는 논리형 자료형이 아닌 정수형, 실수형과 같은 다른 자료형에서 사용하게 되면 에러가 발생합니다. 다음으로 비트를 부정하는 '~'연산자에 대해 알아보겠습니다. 이 연산자는 비트 값으로 저장되는 모든 값에 대해 부정의 값을 취할 수 있습니다. 이 자료형은 몇 가지의 특징이 있는데 boolean, float, double의 자료형들은 이 연산자를 사용할 수 없습니다. 그리고 byte, char, short, int형의 자료형들은 이 연산자를 사용하면 결과값을 int형이나 long형의 자료형에만 저장이 가능하고 long형의 결과값은 long형의 자료형에만 저장이 가능하다는 특징이 있습니다.

 

 - boolean a = false;   // ~a -> X 

   float f = 12.34f;   // ~f -> X

   double d = 12.34;   // ~d -> X

 

   byte b = 12;  // byte c = ~b; -> X, int c = ~b; -> O

   long b = 12L;   // int c = ~b; -> X, long c = ~b; -> O

 

 '~'연산자의 연산 과정은 이러합니다. 모든 자료형은 우선 int형의 비트인 32비트로 변환, long형의 경우 64비트로 변환되어 연산이 수행됩니다. 그리고 이러한 과정의 공식은 아래와 같습니다.

 

 - 피연산자 비트 * (-1) -1;

 

 사칙연산자는 초등학교 때 배우는 것이므로 건너뛰도록 하겠습니다. 이후 +와 -를 2개씩 붙인 증감 연산자( ++/ -- )에 대해 알아보도록 하겠습니다. 이 연산자의 역할은 특정한 값에 1을 더하거나 빼주는 역할을 합니다. 이 연산자의 특징으로는 피연산자의 앞에 쓰이는지 뒤에 쓰이는지에 따라 다른 값을 출력한다는 것입니다. 앞에 붙게되면 연산의 우선순위가 높아 다른 연산자들에 비해 우선적으로 처리되게 됩니다. 하지만 뒤에 붙게 된다면 우선순위가 낮게 되어 다른 모든 연산이 된 후에 연산될 것입니다. 아래의 소스를 예시로 보겠습니다.

public class Round05_Ex01 {

	public static void main(String[] args) {
		
		int x = 5;
		int y = ++x;
		System.out.println("x = "+x);
		System.out.println("y = "+y);

	}

}

  위의 코드를 실행시켜보면 둘 다 값이 6으로 나오는 것을 확인할 수 있습니다. 이는 x가 5로 선언이 되었지만 y에 값을 저장하면서 전위 연산자인 ++을 통해 x의 값에 1이 우선적으로 더해지고 y에 그 1이 더해진 x의 값이 저장되면서 둘 다 6이 되었기 때문에 둘 모두 6으로 출력될 수 있는 것입니다. 그럼 반대로 아래의 소스를 보도록 하겠습니다.

public class Round05_Ex02 {

	public static void main(String[] args) {
		
		int x = 5;
		int y = x++;
		System.out.println("x = "+x);
		System.out.println("y = "+y);

	}

}

 이 코드를 실행하게 되면 아까와는 다른 6과 5가 각자 출력이 될 것입니다. 이는 아까와 과정은 비슷하지만 y에 값을 저장하는 과정에서 x에 1이 더해진 값이 저장되는 것이 아닌 1이 더해지기 전의 값(5)가 저장이 되고 1이 더해지기 때문에 6과 5가 출력되는 결과를 얻을 수 있습니다. 이번에는 하나의 연산자가 아닌 다른 연산자들도 같이 있는 경우를 보도록 하겠습니다.

 

 - int a = 10;

   3+ ++a * 10   // 이 경우에는 3 + 11 * 10이 되므로 113이 됩니다.

 

 - int a = 10;

   3+ a++ * 10   // 이 경우에는 3 + 10 * 10이 되므로 103이 됩니다. 하지만 x의 값은 동일하게 11이 됩니다.

 

 이번에는 형변환인 '(cast)'에 대해서 알아보도록 하겠습니다. 'cast'의 정확한 이름은 'Casting'으로 자동 형변환을 'Up Casting', 강제 형변환을 'Down Casting'이라고 합니다. 이 캐스팅은 별다른 의미가 없으므로 우선순위가 꽤 높다는 것만 알아두고 넘어가도록 하겠습니다.

 

4. 산술 연산자

 산술 연산자는 초등학교에서 배우는 사칙연산이라고 볼 수 있습니다. 따라서 개념에 있어서 어려운 부분은 없으나 주의할 점이 있습니다. 자료형에 따라서 우선순위가 다르다는 것입니다. 우선 정수형 자료형을 보도록 하겠습니다. 정수형 자료형에서의 산술 연산자는 byte, short, char, int형 사이에서의 결과가 int 자료형이 된다는 것입니다. 아래의 예시를 보도록 하겠습니다.

 

 - byte b = 10;

   short s = 20;

   b + s = 30 ( int형의 결과 )

 

 이번에는 실수형 자료형들의 연산에 대해 알아보도록 하겠습니다. long, float, double 자료형이 연산에 개입되면 큰 자료형의 결과를 나타내게 됩니다. ( long < float < double )

 

 - 50 + 2L * 3;   // long형 결과 56

   1.2f + 50L - 12;   // float형 결과 39.2

 

 이때 주의할 점은 float과 double 사이에서의 연산을 혼용하면 안된다는 것입니다. 이는 정밀도의 차이 때문에 그런것인데 아래의 코드를 살펴보도록 하겠습니다.

public class Round05_Ex03 {

	public static void main(String[] args) {
		
		float f = 1.2f;
		double d = 1.2;
		double dd = d-f;
		System.out.println(dd);

	}

}

 위의 코드를 실행해보면 0이 아닌 다른 값이 출력되는 것을 확인할 수 있습니다. 때문에 float형과 double형의 혼용 연산은 멀리하는 것이 좋습니다.

 

5. 쉬프트 연산자 

 쉬프트 연산자는 피연산자의 값을 2진 비트로 계산한 후 특정 비트 만큼 왼쪽 혹은 오른쪽으로 옮기는 연산입니다. 쉬프트 연산자 또한 int형보다 작은 자료형은 int형으로의 연산이 작용되고 그보다 큰 자료형인 long형에서는 64비트 연산이 일어나게 됩니다. 이 때 쉬프트 연산자는 논리형인 boolean과 실수형 자료형인 float, double에서는 사용할 수 없습니다. 쉬프트 연산자는 좌쉬프트 연산자와 우쉬프트 연산자로 나눌 수 있습니다.

 

 1] Left Shift 연산자( << )

  이 연산자는 피연산자의 값을 2진 비트로 변환 후 왼쪽으로 연산을 진행합니다.

 

  예) 1 << 3

       이동 전 : 0000 0000 0000 0000 0000 0000 0000 0001   // 10진수로 1

       이동 후 : 000 0000 0000 0000 0000 0000 0000 0000 1000   // 10진수로 8

       연산 후 32비트 밖으로 밀려난 0은 버려주고 가장 끝에 이동시킬 수 만큼의 0을 붙여줍니다

       공식 : (피연산자의 값) * 2^(이동 비트 수)

 

 2] Right Shift 연산자( >> )

  이 연산자는 위의 Left Shift 연산자와 반대로 계산해주는 연산자 입니다. 이때 피연산자의 값이 양수면 0으로 채우고 음수면 1로 채우게 됩니다.

 

  예) -8 >> 3

       이동 전 : 1111 1111 1111 1111 1111 1111 1111 1000   // 10진수 값 -8

       이동 후 : 1111 1111 1111 1111 1111 1111 1111 1111   // 10진수 값 -1

 

  공식 : (피연산자의 값) / 2^(이동 비트 수)

 

 3] Unsigned Right Shift 연산자( >>> )

  이 연산자는 Right Shift 연산자와 기본원리는 같으나 피연산자의 값이 음수일 때도 앞에 0을 채운다는 점에서 다릅니다. 이 연산을 사용하게 되면 피연산자의 값에 상관없이 무조건 양수의 값이 나오게 됩니다.

 

  예) -8 >>> 3

       이동 전 : 1111 1111 1111 1111 1111 1111 1111 1000   // 10진수 값 -8

       이동 후 : 0001 1111 1111 1111 1111 1111 1111 000   // 10진수 값 536870911

 

 자바에서 사용하는 기본 메모리는 32비트입니다. 그리고 가끔씩 메모리의 절약을 위해 int형 하나의 데이터에 16비트씩 2개의 데이터를 사용하거나 8비트씩 4개의 데이터를 사용하는 경우가 있습니다. 이때 상위의 16비트를 뽑아낸다던가 하위의 16비트를 뽑아내려 할 때 이 쉬프트 연산자를 사용하면 됩니다.

'프로그래밍 > JAVA' 카테고리의 다른 글

자바 연산자 - 문제  (0) 2019.04.16
자바 연산자 - 2  (0) 2019.04.15
자바 기본 입출력 - 문제  (0) 2019.04.11
자바 기본 입출력  (0) 2019.04.10
자바 문법 및 자료형  (0) 2019.04.09

1. 하나의 문자를 입력받아 char형 문자와 아스키 코드 값을 출력하는 코드 작성

 

 - 해답

import java.io.*;

public class Test1 {

	public static void main(String[] args) throws IOException {
		
		char ch = (char)System.in.read();
		int i = (int)ch;
		System.in.read();
		System.in.read();
		System.out.println(ch);
		System.out.println(i);

	}

}

 

2. 한 사람의 이름을 입력, 국영수의 점수를 입력받아 총점, 평균을 출력하는 코드 작성

 

 - 해답

import java.io.*;

public class Test2 {

	public static void main(String[] args) throws IOException {
		
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		
		String name="";
		String str="";
		int kor, eng, mat;
		
		System.out.print("이름 : ");
		name = in.readLine();
		System.out.print("국어 : ");
		str = in.readLine();
		kor = Integer.parseInt(str);
		System.out.print("영어 : ");
		str = in.readLine();
		eng = Integer.parseInt(str);
		System.out.print("수학 : ");
		str = in.readLine();
		mat = Integer.parseInt(str);
		
		System.out.println(name+"님 당신의 점수는 다음과 같습니다");
		System.out.println("총점 : "+(kor+eng+mat));
		System.out.println("평균 : "+(double)((kor+eng+mat)/3.0));

	}

}

 위의 코드에서 정수형 변수들에는 in.read() 메소드를 통해서 형변환 작업 없이 바로 입력받으려 했는데 오류가 발생했습니다. 원인을 아시는 분은 댓글에 적어주시면 감사하겠습니다.

'프로그래밍 > JAVA' 카테고리의 다른 글

자바 연산자 - 문제  (0) 2019.04.16
자바 연산자 - 2  (0) 2019.04.15
자바 연산자 - 1  (0) 2019.04.14
자바 기본 입출력  (0) 2019.04.10
자바 문법 및 자료형  (0) 2019.04.09

1. System 클래스

 안녕하세요. 이번 시간에는 자바에서 System 이라는 클래스에 대해 알아보도록 하겠습니다. 우선 이 System 클래스의 역할은 매우 중요합니다. 대부분의 입력을 받거나 출력을 할 때 모두 System 클래스를 통해서 하게 됩니다. 그렇다면 이러한 System 클래스 안에는 어떤것이 있는지 알아보도록 하겠습니다.

 

 1] Fields

  - in : InputStream과 연결된 객체, 키보드로부터 받은 입력을 처리

  - out : PrintStream과 연결된 객체, 콘솔로의 출력을 처리

  - err : PrintStream과 연결된 객체, 콘솔로의 출력처리가 가능하나 일반적으로 에러를 표시할 때 사용

 

 2] Methods

  - currentTimeMillis() : 현재 시간을 1970.1.1 00:00:00를 기준으로 밀리초(msec)로 환산한 long형의 값을 반환

  - exit(int x) : 현재 실행 중인 프로세스를 x라는 조건으로 종료

  - gc() : Garbage 컬렉터의 실행을 유도

  - getProperties() : 현재의 프로그램과 JVM의 실행 정보를 Properties라는 클래스형으로 반환

  - getSecurityManager() : 현재 시스템의 보안 관리자 모드를 SecurityManager라는 클래스형으로 반환

  - load(String f) : 특정 코드나 동적 라이브러리를 실행하기 위해 호출

  - nanoTime() : 현 시간을 나노초(nsec)로 표시

  - setIn(InputStream is) : 입력의 방향을 리다이렉션(Redirection)

  - setOut(PrintStream ps) : 출력의 방향을 리다이렉션

  - setErr(PrintStream ps) : 에러 출력의 방향을 리다이렉션

  - setProperties(Properties p) : Properties 전체를 등록

  - setProperty(String key, String value) : key와 value의 쌍으로 하나의 Property를 등록

  - setSecurityManager(SecurityManager s) : 보안 관리자의 정보를 등록

 

 이러한 필드와 그에 해당하는 메소드들이 있습니다.

 

2. 기본 출력

 자바의 기본 출력은 아래와 같이 사용할 수 있습니다.

 

 - System.out.print((int x));

 - System.out.println((int x));

 - System.out.printf("%d", (int x));

 

 위의 내용은 모두 정수형으로 선언된 x라는 변수를 출력하는 코드입니다. 하지만 약간씩 다른 점이 있습니다. 이제 하나씩 파헤쳐보도록 하겠습니다. 우선 첫번째 문장인 'System.out.print((int x));'는 단순히 x를 출력하고 끝내는 문장이므로 생략하겠습니다. 아래에 있는 'System.out.println((int x));'는 위와 비슷하지만 'ln'이 붙어있습니다. 자바에서 이 'ln'이 붙어있으면 출력을 하고 한 줄을 띄우라는 의미입니다. 마치 엔터를 눌렀을 때와 마찬가지입니다. 그리고 마지막은 C언어에서 출력할 때 사용하는 printf(); 함수와 같은 개념이라고 볼 수 있습니다.

 

 출력을 할 때에는 변수가 어떻게 선언되어 있는지에 상관없이 모든 것을 출력할 수 있습니다. 위의 예시에서 x가 정수형이든 소수형이든 String 자료형이든간에 상관 없이 모두 출력이 가능합니다. 또 굳이 변수가 아닌 일반 상수, 혹은 문자를 바로 출력할 수도 있습니다. 아래의 예시를 통해 보도록 하겠습니다.

 

 - int x=10;

   String str='asdf';

   System.out.println(x);

   System.out.println(str);

 

 - System.out.println(10);

   System.out.println('asdf');

 

 위의 예시는 모두 10을 출력하고 줄을 바꾼 후 asdf를 출력하는 코드이지만 다르게 표현이 가능한 것을 확인할 수 있습니다. 다음은 출력문의 실제 예제를 살펴보도록 하겠습니다.

public class Round04_Ex01 {

	public static void main(String[] args) {
		
		System.out.println("ABC");
		System.out.println("DEF");
		
	}

}

 위의 코드를 실행하면 아래와 같은 결과를 얻을 수가 있습니다.

 만약 위의 코드에서 'System.out.println'이 아닌 'System.out.print'을 사용한다면 'ABCDEF'와 같은 결과가 나오게 됩니다. 그렇다면 이번에는 다른 코드를 살펴보겠습니다.

public class Round04_Ex02 {

	public static void main(String[] args) {
		
		byte by = 12;
		System.out.println(by);
		short sh = 12;
		System.out.println(sh);
		char ch = 12;
		System.out.println(ch);
		int i = 12;
		System.out.println(i);
		long lo = 12L;
		System.out.println(lo);
		float fl = 12.0f;
		System.out.println(fl);
		double dou = 12.0;
		System.out.println(dou);
		
	}

}

 이 코드는 앞서 배웠던 자료형을 모두 출력해보는 코드입니다. 그렇다면 모두 출력했을 때 12가 출력이 되는지 확인해보도록 하겠습니다.

 다른 것들은 모두 제대로 출력되는 반면, 3번째인 char 자료형은 이상한 문자가 출력되는 것을 확인할 수 있습니다. 이는 char 자료형은 문자 기준이기 때문에 12를 아스키 값으로 인식하여 해당 아스키값에 대응하는 문자를 출력하게 되는 것입니다. 만약 정수 12를 출력하고 싶다면 형변환을 통해 'System.out.println((int)ch);'를 입력해주면 됩니다.

 

 C언어에서는 출력문에서 변수와 문자열을 동시에 출력할 때에는 ""안에 %d와 같이 변수의 출력을 암시해주는 표시와 같이 자연스럽게 출력할 수 있으나 자바에서는 약간의 차이점이 있습니다. 자바에서는 모든 것을 출력할 때에는 +를 통해 사이를 띄어주어야 합니다. 예를 들어 10이라는 값의 i변수가 있고 'i의 값은 10(==i)입니다'를 출력하고 싶을 때는 아래와 같이 입력해주어야 합니다.

 

 - System.out.println("i의 값은"+i+"입니다");

 

 하지만 이렇게 됐을 경우 문제가 생깁니다. 만약 변수의 값을 더하는 것이 아니라 나열을 하고 싶을 때 a+b와 같은 방법으로 표현을 하면 a와 b를 더한 값이 출력이 되어버립니다. 이를 해결하기 위해서는 공백을 앞에 입력하고 위와 같이 입력해주면 됩니다. 아래의 예시를 통해 알아보겠습니다.

 

 - int a = 1;

   int b = 2;

   System.out.println(""+a+b);

 

 위와 같이 입력을 하게 되면 3이 아닌 12가 출력이 됩니다. 이는 덧셈이 왼쪽에서 오른쪽으로 연산이 되는 원리로 공백과 a가 먼저 계산되고 후에 b의 값이 연산이 되므로 "1"+2가 되는 셈입니다.(공백+1) 이후의 연산을 통해 "12"의 값이 출력이 되는 것입니다.( ※문자열은 어떤 것과 연산돼도 문자열이 되어버리는 성질이 존재 )

 

 그렇다면 이제 %를 통해서 어떠한 것들을 출력할 수 있는지 알아보도록 하겠습니다.

 

 - %c : char 문자 1개를 출력

 - %숫자c : char 문자 1개를 숫자만큼 공백 생성 후 출력

              예) a가 1이고 %5c를 통해 출력했다면 = '     1' 출력

 - %d : byte, short, int, long형의 데이터를 10진수로 출력( %o=8, %x=16 )

 - %숫자d : byte, short, int, long형의 데이터를 숫자만큼 공백 확보 후 출력

 - %0숫자d : 위와 같은 형식이되 확보한 자리가 공백이면 0 값을 공백에 채우게 하는 형식

 - %f, %g, %e : float, double형의 데이터를 출력

 - %숫자f, %숫자g, %숫자e : float, double형의 데이터를 숫자만큼의 공백 확보 후 출력

 - %0숫자f : 위와 같은 형식이되 확보한 자리가 공백이면 0 값을 공백에 채우게 하는 형식 

               * 이 형식은 10.2와 같이 소수로도 표현이 가능한데 이 의미는 10개의 공백을 채우고 소수점은 2자리까지만 

                 나타내라는 뜻 

 - %s : 문자열 데이터를 출력하는 서식

 - %숫자s : 문자열 데이터를 숫자만큼의 공백 확보 후 출력

 

 이러한 서식들을 이해하기 위해 간단한 예제를 보도록 하겠습니다.

public class Round04_Ex03 {

	public static void main(String[] args) {
		
		System.out.printf("%c", 'A');
		System.out.println();
		System.out.printf("%5c", 'A');
		System.out.println();
		System.out.printf("%-5c", 'A');
		System.out.println();
		System.out.println();
		System.out.printf("%d", 12345);
		System.out.println();
		System.out.printf("%o", 12345);
		System.out.println();
		System.out.printf("%x", 12345);
		System.out.println();
		System.out.printf("%10d", 12345);
		System.out.println();
		System.out.printf("%010d", 12345);
		System.out.println();
		System.out.println();
		System.out.printf("%f", 12.12745f);
		System.out.println();
		System.out.printf("%g", 12.12745f);
		System.out.println();
		System.out.printf("%e", 12.12745f);
		System.out.println();
		System.out.printf("%-10.2f", 12.12745f);
		System.out.println();
		System.out.printf("%010.2f", 12.12745f);
		System.out.println();
		
	}

}

 위의 예제의 결과는 이렇습니다.

 이처럼 다양하게 표현되는 것을 확인할 수 있습니다.

 

3. 예외 처리

 자바에서는 입출력에 관한 것을 처리할 때에는 항상 예외 처리라는 것을 해주어야 합니다. 만약 예외처리를 하지 않는다면 컴파일조차 실행되지 않습니다. 하지만 지금까지 배웠던 printf나 print, println과 같은 메소드를 사용할 때에는 별다른 예외 처리를 하지 않아도 잘 실행됐었는데 이는 이 메소드들은 모두 예외 처리가 되어 있는 메소드들이기 때문에 그렇습니다. 아래의 예시를 통해 알아보도록 하겠습니다.

import java.io.*;

public class Round04_Ex05 {

	public static void main(String[] args) {
		
		byte[] bb = {'J', 'A', 'V', 'A'};
		System.out.write(bb);

	}

}

 우선 위의 코드가 어떤 내용인지 알아보도록 하겠습니다. 이 코드는 bb라는 배열을 생성하여 각 칸에 'J', 'A', 'V', 'A'를 넣어주고 System.out 안의 write(bb)메소드를 통해 bb의 요소들을 모두 출력하는 코드입니다. 위의 코드를 그냥 실행한다면 에러가 발생하면서 컴파일이 되지 않는 것을 확인할 수 있습니다. 이는 write()메소드는 기본적인 예외 처리가 되어 있지 않기 때문인데 아래와 같이 수정해주면 잘 작동하는 것을 확인할 수 있습니다.

import java.io.*;

public class Round04_Ex05 {

	public static void main(String[] args) throws IOException {
		
		byte[] bb = {'J', 'A', 'V', 'A'};
		System.out.write(bb);

	}

}

 위의 코드는 전 단계의 코드에서 'public static void main(String[] args)' 부분 뒤에 'throws IOException'을 붙여준 것으로써 IOException(Input Output Exception), 즉 입출력 예외를 던져버리라는 뜻의 문구를 달아준 것입니다.

 

4. 기본 입력

 System.out이 PrintStream과 연결돼있는 클래스라면 System.in은 InputStream(내부적으로는 BufferedInputStream)과 연결돼있는 클래스입니다. System.in 또한 System.out처럼 InputStream 클래스 내의 모든 멤버를 이용할 수 있습니다. 우선 System.in.read()에 대해 알아보도록 하겠습니다.

 

 System.in.read()는 System.out.print()와 반대되는 성격으로 입력을 하는 메소드입니다. 아래의 간단한 코드를 살펴보도록 하겠습니다.

 

 - System.out.println(1);

   System.out.println(2);

   System.in.read();

   System.out.println(3);

 

 위의 코드를 실행한다면 1과 2까지 출력이 됐다가 커서가 깜빡거리면서 사용자의 입력을 기다리게 될 것입니다. 이후에 엔터를 입력하면 3이 출력될 것입니다. 이처럼 단순하게 입력을 처리하는 메소드가 System.in.read()입니다. 이후 사용자가 입력한 값을 어딘가에 저장하고 싶다면 아래와 같이 변수를 생성해준 후 입력해주면 됩니다.

 

 - int a = System.in.read();

 

 위와 같이 입력하면 값이 제대로 저장되는 것을 확인할 수 있습니다. 하지만 이때 아스키코드값에 의하면 0은 0이 아닌 48, 1은 49와 같이 각 숫자로부터 48씩 차이가 나므로 끝에 -48(혹은 '0')을 입력해주어야 합니다.

 

 - int a = System.in.read()-48; / int a = System.in.read()-'0';

 

 이제 문자를 입력받는 방법을 알아보도록 하겠습니다. System.in.read()를 통해 문자를 입력하게 되면 그에 맞는 아스키코드값이 저장되어 A는 65, B는 66과 같이 숫자가 저장이 됩니다. 따라서 문자를 입력하고 싶다면 형변환을 해주어야 합니다. 

 

 - char a = (char)System.in.read();

 

 그럼 실습을 위해 아래의 코드를 살펴보도록 하겠습니다.

import java.io.*;

public class Round04_Ex07 {

	public static void main(String[] args) throws IOException{
		
		System.out.print("입력1 = ");
		char aa = (char)System.in.read();
		System.out.print("입력 2 = ");
		int bb = System.in.read()-48;
		System.out.println("입력된 문자는 = "+aa);
		System.out.println("입력된 문자는 = "+bb);

	}

}

 위의 코드를 실행하고 a를 입력하고 엔터를 누르게 되면 아래와 같은 결과가 나올 것입니다.

 이와 같은 결과가 나타난 이유는 JVM에서 엔터 또한 하나의 입력으로 처리하기 때문입니다. 엔터키의 구조는 '\r\n'으로 조합되어 있는데 결과적으로는 a가 입력되고 \r, \n이 순서대로 입력된 것이나 마찬가지입니다. 두번째 출력에서 -35가 출력된 이유는 \r의 값이 13이고 이에서 -48을 했으므로 -35가 출력된 것입니다. 이를 해결하기 위해서는 아래와 같이 엔터키의 입력을 처리해줄 코드를 추가해야 합니다.

import java.io.*;

public class Round04_Ex07 {

	public static void main(String[] args) throws IOException{
		
		System.out.print("입력1 = ");
		char aa = (char)System.in.read();
        System.in.read();
        System.in.read();
		System.out.print("입력 2 = ");
		int bb = System.in.read()-48;
		System.out.println("입력된 문자는 = "+aa);
		System.out.println("입력된 문자는 = "+bb);

	}

}

 

 지금까지는 하나의 문자를 입력받는 방법에 대해 알아보았습니다. 이제는 여러문자를 입력받는 방법에 대해 알아보겠습니다. 비교적 간단하게 구현할 수 있습니다. 우선 아래의 한 줄을 추가해주도록 합니다.

 

 - BufferedReader in = new BufferedReader(New InputStreamReader(System.in));

 

 이 줄을 추가하고 이후에 입력받을 것은 변수를 선언한 후 in.readLine() 메소드를 사용해주면 됩니다. 아래의 예시를 통해 알아보도록 하겠습니다.

import java.io.*;

public class Round04_Ex09 {

	public static void main(String[] args) throws IOException {
		
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		
		String name = "";
		System.out.print("이름 입력 : ");
		name = in.readLine();
		System.out.println("당신이 입력하신 이름은 : "+name);

	}

}

 또한 readLine() 메소드는 자동으로 엔터키를 처리해주기 때문에 엔터키에 대한 걱정은 하지 않아도 된다는 장점이 있습니다. 이러한 BufferedReader를 통해 선언하는 것은 모두 문자열로 입력받기 때문에 다른 자료형으로 입력받아야 하는 경우에는 형변환을 해주어야 합니다. 아래의 예시를 보도록 하겠습니다.

 

 [ boolean ] 

 - String str = in.readLine();

   boolean bool = Boolean.valueOf(str).booleanValue();

 

 [ int ]

 - String str = in.readLine();

   int i = Integer.parseInt(str);

 

'프로그래밍 > JAVA' 카테고리의 다른 글

자바 연산자 - 문제  (0) 2019.04.16
자바 연산자 - 2  (0) 2019.04.15
자바 연산자 - 1  (0) 2019.04.14
자바 기본 입출력 - 문제  (0) 2019.04.11
자바 문법 및 자료형  (0) 2019.04.09

+ Recent posts