자바 조건문과 반복문 - if, switch, for, while

Chapter 4: 조건문과 반복문

4.1 if 문

실습: 로그인 시스템 만들기

아이디 비밀번호를 입력하면 맞으면 로그인에 성공합니다.

처음 시도:

import java.util.Scanner;

public class LoginIfs {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        String correctId = "seowoo";
        String correctPassword = "super";

        System.out.println("id:");
        String id = sc.nextLine();
        if (id == correctId) {
          System.out.println("password:");
          String pw = sc.nextLine();
          if (pw == correctPassword) {
              System.out.println("로그인에 성공하였습니다.");
          } else {
              System.out.println("비밀번호가 틀렸습니다.");
          }
        } else {
            System.out.println("아이디가 존재하지 않습니다.");
        };
    }
}

질문: 근데 여기서 맞는 아이디를 입력해도 아이디가 존재하지 않는다고 함. 왜지?

<추가된 답변=""> `==`는 문자열의 내용을 비교하지 않습니다! 자바에서 String은 객체, 즉 참조형입니다. `==`로 비교하면 내용이 아니라 같은 객체인지(참조값)를 비교합니다. - `correctId`와 `id`는 다른 객체로 선언되었으므로 둘이 같은지를 비교하면 다르다고 나옵니다. - 문자열의 내용을 비교하기 위해서는 `.equals()` 메서드를 사용해야 합니다. 올바른 비교 방법: ```java if (id.equals(correctId)) { // 올바른 문자열 비교 // ... } // 또는 if (correctId.equals(id)) { // 더 안전 (null 방지) // ... } ``` `==` vs `.equals()`: - `==`: 참조(메모리 주소) 비교 - `.equals()`: 내용(값) 비교 ```java String s1 = new String("hello"); String s2 = new String("hello"); System.out.println(s1 == s2); // false (다른 객체) System.out.println(s1.equals(s2)); // true (같은 내용) ``` </추가된 답변> ## 4.2 switch 문 여러 값 중 하나를 선택하도록 할 때 사용합니다. ### 실습: 계산기 만들기 switch 문의 다양한 방식을 사용해보려고 이렇게 만들었다. ```java import java.util.Scanner; public class CalculatorSwitch { public static void main(String[] args) { Scanner sc = new Scanner(System.in); boolean valid; double result; System.out.println("첫번째 숫자를 입력하세요"); int num1 = sc.nextInt(); System.out.println("연산자를 입력하세요"); String calc = sc.nextLine(); switch (calc) { case "-": case "+": case "/" : case "*": System.out.println("두번째 숫자를 입력하세요"); int num2 = sc.nextInt(); valid = true; break; default: System.out.println("사칙연산만 가능합니다."); valid = false; break; }; if (valid) { switch(calc) { case "-": result = num1 - num2; case "+": result = num1 + num2; case "/": result = num1 / num2; case "*": result = num1 * num2; System.out.print(result); } }; } } ``` ### 질문: 근데 num2가 정의되지 않았다고 하네. 뭐지??? <추가된 답변=""> case 안에서 선언한 변수는 밖에서 못 씁니다. 선언과 초기화는 따로 할 수 있는데, 컴파일러가 코드를 빌드하기 전에 체크하면서 사용하기 전에 초기화되지 않을 수 있는 변수에 대해서는 에러를 뱉습니다. 이 로직의 경우: - 연산자가 제대로 설정되지 않은 경우에 두 번째 숫자도 받지 말라고 했는데 - 그래서 사용하기 전에 초기화가 안 되는 경우가 있을 수도 있다 - 그래서 컴파일러가 컴파일을 안 해주는 것 핵심 개념 - 스코프(Scope): - 변수가 살아있는 범위 - 중괄호 `{}`가 기준이 된다 - 안쪽에서는 바깥 변수 접근 가능 - 바깥에서는 안쪽 변수 접근 불가능 ```java { int outer = 10; { int inner = 20; System.out.println(outer); // OK (안쪽에서 바깥 접근) } System.out.println(inner); // 에러! (바깥에서 안쪽 접근 불가) } ``` </추가된 답변> ### 추가로 발견한 문제들 1. Scanner에서 `nextInt()`나 `nextDouble()`로 받은 후에는 엔터가 버퍼에 남아있어서 `nextLine()`을 쓰면 바로 넘어가 버립니다. - 해결: 버퍼를 비워주거나 `next()`를 사용 2. switch 문에는 `break`가 있어야 아래 케이스가 쭉 실행되지 않습니다 (fall-through 방지) 수정본: ```java import java.util.Scanner; public class CalculatorSwitch { public static void main(String[] args) { // 숫자 두개와 연산자를 받아서 계산하기 Scanner sc = new Scanner(System.in); boolean valid; double result = 0; System.out.println("첫번째 숫자를 입력하세요."); int num1 = sc.nextInt(); System.out.println("두번째 숫자를 입력하세요."); int num2 = sc.nextInt(); System.out.println("연산자를 입력하세요."); String calc = sc.next(); switch (calc) { case "-" : case "+" : case "/" : case "*": valid = true; break; default: System.out.println("사칙연산만 가능합니다."); valid = false; break; } if (valid) { switch (calc) { case "-": result = num1 - num2; break; case "+": result = num1 + num2; break; case "*": result = num1 * num2; break; } System.out.printf("%.2f", result); } } } ``` ## 4.3 for문 별 출력하기 (실습 예제는 튜토리얼 참고) ## 4.4 do-while 문 최소 1번은 실행 후 조건을 검사하는 반복문입니다. ### 실습: 메뉴 시스템 ```java import java.util.Scanner; public class DoWhileExample { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int input; // 메뉴 선택 (0 입력 시 종료) do { System.out.println("\n===== 메뉴 ====="); System.out.println("1. 게임 시작"); System.out.println("2. 설정"); System.out.println("3. 도움말"); System.out.println("0. 종료"); System.out.print("선택: "); input = sc.nextInt(); switch (input) { case 1 -> System.out.println("게임을 시작합니다!"); case 2 -> System.out.println("설정 화면입니다."); case 3 -> System.out.println("도움말 화면입니다."); case 0 -> System.out.println("프로그램을 종료합니다."); default -> System.out.println("잘못된 입력입니다."); } } while (input != 0); sc.close(); } } ```