본문 바로가기

국비과정

[ANDROID 국비과정] 2023.01.18 - 안드로이드 앱 개발자 과정

JAVA


키보드 입력 - System.in => Scanner

Scanner 가 탄생한 배경과 그 필요성에 대해 생각해보자. 

 

 

System in

int a = 0;

// 키보드로부터 입력된 값을 받아서 리턴해주는 기능을 가진 녀석(객체)을 이용.
try {
    a = System.in.read(); // %c 입력과 동일 , 입력된 값을 아스키 코드로 받아들임.
    a = a-48; // 숫자모양의 문자를 숫자로 변환
    System.out.println("덧셈결과 : " + (a + 50));
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.getMessage();
}

 

키보드로 부터 입력을 받고싶습니다. C 언어에서는 scanf_s() 라는 함수를 이용했지만, Java 에서는 System.in 이라는 객체를 사용하여 read() 메소드를 통해 입력을 받습니다. (여기서 System 은 클래스이며, in은 static으로 작성된 멤버변수이며 참조변수 입니다. 즉, System 클래스가 사용될 때, 객체 in 은 메모리에 올라갑니다.) 위 코드는 키보드로 입력을 받아, 덧셈결과를 출력해주는 코드입니다. 다만, read() 메서드의 경우 한 문자만 입력받도록 되어있으며, 아스키 값으로 받아들입니다. 만일 정수를 출력해주고 싶다면 아스키 값을 정수로 바꿔주는 로직이 따로 필요합니다.

 

 

 

3자리 숫자 입력받기

 

// 3자리 숫자 입력받아 보기
int num = 0;
try {
    int n;
    n = System.in.read();
    num += (n - 48) * 100;

    n = System.in.read();
    num += (n - 48) * 10;

   n = System.in.read();
    num += n - 48;

    System.out.println(num);
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

앞서 read() 메서드는 한 문자를 아스키 값으로 입력받는다고 하였습니다. 그래서 정수를 출력하고 싶다면 아스키 값을 정수값으로 바꿔주는 로직이 필요합니다. 그러면 3자리 숫자라면 어떨까요? 3자리 숫자라고 달라지는것은 없습니다. 다만 로직이 더 복잡해질 뿐입니다. 그러면 4자리,5자리,100자리까지 가면 굉장히 복잡해질것같은 예감이 듭니다. 그래서 Java 에서는 Scanner 라는 클래스를 만들었습니다.

 

 

Scanner 클래스

// 사용자로부터 2개의 정수를 입력받아 덧셈하는 프로그램

int a, b;
Scanner scan = new Scanner(System.in);

System.out.print("숫자입력 1 : ");
a = scan.nextInt();

System.out.print("숫자입력 2 : ");
b = scan.nextInt();

System.out.print(a + " + " + b + " = " + (a + b));

Scanner 클래스는 편리하게 키보드 입력을 받을 수 있게 도와주는 클래스 입니다. System.in 이 받아오는 아스키값을 자료형으로 바꿔주는 역할을 합니다. 그리고 위 코드에서 주의깊게 봐야할 코드는 다음 한줄입니다.

Scanner scan = new Scanner(System.in);

 

Scanner scan
=> Scanner 클래스의 참조변수 scan 을 선언했습니다.


new Scanner(System.in)
=> new 연산자를 통해 Scanner 객체의 Heap 메모리 공간을 만들어 주었습니다. 또한 생성자 메서드를 통해 파라미터로 System.in 객체를 전달해주어 키보드 입력값을 전달해주었습니다.


Scanner scan = new Scanner(System.in);
=> 앞서 선언한 참조변수 scan 에 Scanner 객체의 주솟값을 전달해주었습니다.

 

 


Random 클래스

Random 클래스도 Scanner 클래스와 똑같습니다. 다음 코드 한줄을 보겠습니다.

 

Random rand = new Random();

 

Random rand
=> 자료형이 Random 인 참조변수 rand 를 선언하였으며, 이 참조변수는 메모리상으로 Stack 에 올라가게 됩니다.

 

new Random()
=> new 연산자를 통해 Random 클래스를 인스턴스화 하여 객체로 만들었습니다. 이때 객체는 Heap 메모리에 올라가며, 생성자 함수또한 이때 호출 됩니다.


Random rand = new Random();
=> 참조변수 rand 로 Heap 메모리에 올라가있는 Random 객체의 주솟값을 받아왔습니다.

 

이러한 원리에 의해서 참조변수를 가지고 Random 객체에 있는 메서드나 변수에 접근할 수 있게 됩니다.

 

다음 코드는 Random 클래스의 사용예시 입니다.

    // 0 ~ 9 까지 10개의 숫자 중에 하나가 랜덤하게 나오도록 하고싶다!
    int b;
    b = rand.nextInt(10);
    System.out.println(b);

    // 5 ~ 15
    int c = rand.nextInt(11) + 5;
    System.out.println(c);

    // -5 ~ 5
    int d = rand.nextInt(11) - 5;
    System.out.println(d);

    // 랜덤한 실수값 얻어오기
    double e = rand.nextDouble();
    System.out.println(e);

    // 0.0 ~ 9.9999
    double f = rand.nextDouble() * 10;
    System.out.println(f);

    // 논리값 랜덤
    boolean g = rand.nextBoolean();
    System.out.println(g);

 


연산자

// 새로 추가된 연산자 [비트연산자 : >>> - 부호 비트까지 밀어버림] 
System.out.println(-8 >>> 1); // 부호가 바뀜! 숫자결과값도 바뀜..
System.out.println(3.1 % 2);
// 주소나 메모리 사이즈 보는 연산자 없음.
int n;
// System.out.println( &n ); // error - 주소연산자 없음
// System.out.println( sizeof(n) ); // error - 메모리를 보는 기능이 없음.

자바의 연산자는 C와 동일합니다. 간단하게 위 주석들만 보고 넘어가면 될것같습니다.

 


제어문

String s1 = "Hello";
String s2 = "Hello";

System.out.println(s1 == s2); // false : 주소끼리 비교
System.out.println(s1.equals(s2)); // true : 값끼리 비교

제어문 역시 C언어와 동일합니다. 바뀐점은 while 문을 무한루프 시킬 때, 조건값으로 1이 아닌 true 논리값을 주어야 한다는 점입니다. 또한, switch 문의 경우 C에서는 char 형과 int 형 변수만 가능하였으나, 자바에서는 String 문자열 까지 가능합니다. 여기서 주의깊게 볼 부분은 문자열의 비교에 관한 내용입니다.

 

위 코드에서 문자열 s1 과 s2 를 선언했습니다. 값으로는 Hello 를 넣었습니다. 여기서 이 두 문자열이 같은 문자열인지 비교해보고 싶습니다. 우리는 비교연산자 ==를 알고있습니다. 보통 정수값을 비교할 때 5 == 5 이면 참이라고 결과값이 나오는 그 비교연산자 입니다. 그러면 문자열에서도 마찬가지로 비교연산자를 통해 문자열을 비교할 수 있을까요? 결론부터 말하자면 못합니다. String 은 클래스 입니다. 그리고 참조변수 s1,s2 를 통해 "Hello" 의 주솟값을 받아올 뿐입니다. 사실, "Hello" 는 값 처럼 보이지만 다음 코드와 같습니다.

 

"Hello" => new String("Hello");

 

그리고 아래 그림처럼 참조변수가 가지고 있는 주솟값은 서로 다릅니다. 그렇기 때문에 s1 == s2 를 비교하게 된다면 예상하던 결과값 과는 차이가 있을겁니다. 그래서 Java 에서는 String 객체가 가지고 있는 equals() 메서드를 통해 문자열을 비교해야 합니다.