이것이 자바다 2일차 - Chapter 4 조건문과 반복문

Seo-Faper·2023년 1월 10일
0

이것이 자바다

목록 보기
2/20

자바 뿐만 아니라 어지간한 프로그래밍 언어들은 모두 가지고 있는 조건문과 반복문이다.
이 조건문과 반복문의 가장 큰 목적은 바로 코드 실행의 흐름 제어 이다.

조건문반복문
if, switchfor, while, do-while

if문

if문은 조건식의 결과가 true 인지 false인지 에 따라 블록 실행 여부가 결정된다.

if(score < 90) {
 	System.out.println("점수가 90보다 작습니다.");
 	System.out.println("등급은 B 입니다.");
}
System.out.println("이 줄은 if문과는 상관없는 실행문 입니다.");

score라는 변수가 90보다 작아서 true가 된다면 if문 블럭 안의 2줄을 실행한 후 아래의 마지막 문장을 출력한다. 또한, if문은 한줄만 쓰게 될 시 중괄호 { ~ }를 생략 할 수 있다.

if(score < 90) System.out.println("점수가 90보다 작습니다.");
 	System.out.println("등급은 B 입니다.");
System.out.println("이 줄은 if문과는 상관없는 실행문 입니다.");

그래서 이렇게 쓰게 될 시 "등급은 B 입니다." 또한 if문과는 상관없는 실행문이 된다.
또한 if문에서는 else 라는 키워드를 사용할 수 있다. if문은 else 블럭과 함께 사용되어 조건식의 결과에 따라 실행 블록을 선택할 수 있다.

 if(score >= 90) {
 	System.out.println("점수가 90보다 큽니다.");
    System.out.println("등급은 A 입니다.");
 } else { // <--score <90 일 경우
    System.out.println("점수가 90보다 작습니다.");
    System.out.println("등급은 B 입니다.");
 }

if-else문의 특징은 첫번째 if문의 조건식의 부정 형태가 else의 조건식이 된다는 것이다.
즉, 오직 한 조건식의 true / false의 여부에 따라서만 코드를 짤 수 있기 때문에 else 뒤에 if를 한번 더 써서 흐름 제어를 하는 것이 가능하다.

 if(score >= 90) {
 	System.out.println("점수가 100~90 입니다.");
    System.out.println("등급은 A 입니다.");
 } else if(score >=80 ) { 
    System.out.println("점수가 80 ~ 89 입니다.");
    System.out.println("등급은 B 입니다.");
 } else{
 	System.out.println("점수가 80점 미만입니다.");
 }

그리고 if문 안에 한번 더 if문을 중첩할 수도 있다. 이때는 더욱 복잡한 실행흐름이 된다.
if-else가 계속 될 수록 복잡해지고 분석이 어려지기 때문에 가독성을 높이기 위해 switch문을 사용한다.


Switch 문

switch문은 if문과 다르게 기준이 되는 변수의 값에 따라서 어떤 코드를 실행 할 지 정할 수 있기 때문에 더욱 코드가 간결해 진다.

switch(변수){
	case1:
    	...
        break;
    case2:
    	...
        break;
    default:
    	...
        
}

근데 경험상 switch문은 if-else가 3번 이상 중첩되지 않는 이상 잘 쓰지 않는다.
왜냐하면 저기 break가 없으면 그 아래의 case를 break 만날 때 까지 모두 실행하기 때문이다.
반복문에서 break를 사용하는 경우가 많은데, switch문을 쓰기 위해 boolean flag = true 를 만들어서 컨트롤 하는 건 if-else를 쓰는 것 보다 복잡하다.

그러나 java12 부터 이런 고충을 해결하기 위해 Expressions를 지원하게 되었다.

        switch (grade){
            case 'A','a'->{
                System.out.println("우수회원 입니다.");
            }
            case 'B','b'->{
                System.out.println("일반 회원입니다.");
            }
            default -> {
                System.out.println("손님입니다.");
            }

        }

그리고 java13 부터 switch문의 결과를 변수에 대입하는 기능인 yield 라는 키워드가 추가되었다.

        //Java 12 문법
        int score2 = switch (grade){
            case "A"-> 100;
            case "B"-> {
                int result = 100 - 20;
                //Java 13 문법
                yield result;
            }
            default -> 60;
        };
        System.out.println("score2: "+score2);

단순히 대입을 할 때는 중괄호를 생략하고 100을 대입하면 되지만
특정 코드를 실행해야 한다면 중괄호로 연산을 해 주고 마지막 결과를 yieled result; 해서 대입할 수 있다. 주의할 점은 반드시 default 키워드를 사용해 줘야 한다.


for문

반복문은 특정 실행문을 여러번 반복하고 싶을 때 사용하는 문법이다.

	for(1.초기화식; 2.조건식; 3.증감식) {
    	...
    }

여기서 조건식이 true일 때만 해당 for문안을 계속 반복한다.

        for(int i = 1; i<=10; i++){
            System.out.print(i+" ");
        }

변수 i가 10이 되는 순간 10 <= 10 이므로 구문으로 들어와 System.out.print("10 ");
을 출력하고 i는 11이 된다. 그리고 다시 검사했을 땐 11 <= 10 이 false 이므로 반복문이 종료되고 1부터 10까지 출력되는 것이다.

그리고 초기화식에서 만약 정수 대신 실수를 사용할 경우 부동소수점을 쓰는 float를 사용 하면 편차에 의해 정상적으로 작동 안할 수도 있다.

        for(float x= 0.1f; x<=1.0f; x+=0.1f){
            System.out.println(x);
        }

while문

for문은 반복할 횟수를 미리 정해놓고 짠다면 while문은 조건식이 flase가 될 때 까지 무한히 반복한다는 특징이 있다. 엄밀히 말하자면 for문과 while문도 동일하게 조건이 false가 될 때 까지 반복하는 거지만, for문은 변수를 카운팅 함으로서 조건을 false로 만들고 while은 그 외적인 조건을 컨트롤한다. 주로 크기가 얼마나 될지 모르는 외부 파일을 버퍼 스트림으로 읽을 때, 특정 키를 눌러야만 게임이 종료되는 경우, 반복 횟수를 예측할 수 없을 때 사용한다.

 int i = 1;
while (i <=10){
     System.out.println(i+" ");
     i++;
}

앞서 배운 for문을 그대로 while로 옮긴 것이다.
보통 while문의 경우 while(조건식) 안에 실제 조건식을 넣기 보다는 boolean 변수를 flag로 쓰거나 while(true)로 시작해서 if(조건) break; 를 쓴다.

boolean run = true;
        int speed = 0;

        while (run){
            System.out.println("------------------");
            System.out.println("1. 증속 | 2. 감속 | 3. 중지");
            System.out.println("------------------");
            System.out.print("선택>");

            String strNum = sc.nextLine();

            if(strNum.equals("1")){
                speed++;
                System.out.println("현재 속도 : "+speed);

            }else if(strNum.equals("2")){
                speed--;
                System.out.println("현재 속도 : "+speed);
            }else if(strNum.equals("3")){
                run = false;
            }
        }System.out.println("프로그램 종료");

그 다음으로 알아볼 것은 do-while 문이다.


do-while문

do-while문은 while문과 거의 똑같지만 최초실행 1회를 보장한다는 특징이 있다.

do{
	...
} while(조건문)

여기서 코드 흐름이 반드시 do를 먼저 거치기 때문에 시작부터 조건문이 false라서 아에 while문 자체를 돌지 않는 현상은 일어나지 않는다. while(조건문)이 시작부터 false라도 do의 블럭을 한번 거치고 멈춘다. 해당 구문은 예외를 줄이고 더욱 안전하게 코딩하기 위해 있는 기능이다.


break 문

break; 는 말 그대로 for, while, do-while 구문을 중지할 때 사용한다.

그런데 앞서 말했듯 for문과 switch등이 중첩될 때 break를 만나면 가장 가까운 구문만 빠져나온다는 문제가 있다. 그래서 label을 통해 break를 조절해 줄 수 있다.

 Outter: for(char upper = 'A'; upper<='Z'; upper++){
            for(char lower = 'a'; lower<='z'; lower++){
                System.out.println(upper+"-"+lower);
                if(lower=='g'){
                    break Outter;
                }
            }
        }

이렇게 반복문이 시작하기 전에 라벨명:for ... 으로 라벨을 선언 할 수 있고 break 뒤에 라벨명을 써주면 해당 라벨 이하의 반복문을 종료시킨다.


continue 문

continue; 는 반복문 안에서 사용 할 수 있으며, continue; 아래의 구문을 무시한 체 다시 처음 반복으로 돌아간다. 말로 쓰면 이해가 잘 되지 않으니 예제로 보겠다.

		for(int i = 1; i <=10; i++){
            if(i%2 != 0){
                continue;
            }
            System.out.println(i+" ");
        }

여기서 if문을 만족할 때, 즉 i가 홀수 일 때 if문 블럭으로 들어온다.
그 때 continue를 만나게 되고 아래의 System.out.println(i+" ");를 출력하지 않은 체 다시 for문의 최상단으로 올라간다. 그래서 출력결과는 다음과 같다.

2
4
6
8
10

연습문제

2번, int, double 뿐만 아니라 String, char도 가능하다.

이건 자바 13 부터 쓰는 yield와 자바 12부터 쓰는 키워드 (->)를 활용하면 된다.

String grade = "B";

int score1 = switch(grade){
	case "A" -> 100;
    case "B" ->{
    	int result = 100 - 20;
        yield result;
    }
    default -> 60;
}

int result = 0;
for(int i = 1; i<=100; i++){
	if(i % 3 == 0) result += i; 
}
System.out.println(result);

i % 3 == 0 이 i가 3의 배수면 참이 되므로 원하는 결과를 얻을 수 있다.

while(true)
{
	int a = (int)(Math.random()*6) + 1;
    int b = (int)(Math.random()*6) + 1;
    System.out.println("("+a+","+b+")");
    if((a + b) == 5) break;
}

랜덤 1~6을 2개 a,b에 각각 할당해 주고 if문에 합이 5인지를 구분하는 코드를 넣어주면 된다.

for(int x = 1; x<=10; x++){
	for(int y = 1; y <=10; y++){
    	if((4*x + 5 * y) == 60) System.out.println("("+x+","+y+")");
    }
}

5번과 비슷한 문제다.

for(int i = 1; i <= 5; i++){
            while(true){
                int ran = (int)(Math.random()*Integer.MAX_VALUE)+1;
                if(ran == i){
                    for(int j = 0; j<ran; j++) System.out.print("*");
                    break;
                }
            }
            System.out.println();
        }

ㅋㅋㅋ 이론상 운만 좋으면 바로 출력될 수도 있다.

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
    
       Scanner sc = new Scanner(System.in);
       int myAccount = 0;
       
        while (true){
           System.out.println();
           System.out.println("------------------------------------");
           System.out.println("1. 예금 | 2. 출금 | 3. 잔고 | 4. 종료");
           System.out.println("------------------------------------");
           System.out.print("선택> ");
           
           String userSelect = sc.nextLine();
           
           if(userSelect.equals("1")){
               System.out.print("예금액>");
               myAccount += (Integer.parseInt(sc.nextLine()));
           }else if(userSelect.equals("2")){
               System.out.print("출금액>");
               myAccount -= (Integer.parseInt(sc.nextLine()));

           }else if(userSelect.equals("3")){
               System.out.print("잔고>");
               System.out.println(myAccount);

           }else if(userSelect.equals("4")){
               System.out.println("프로그램 종료");
               break;
           }
        }
    }
}
profile
gotta go fast

0개의 댓글