백기선 자바 스터디 4주차

김성훈·2022년 7월 16일
0
post-thumbnail

자바가 제공하는 제어문을 학습하세요


학습할 것

선택문
반복문


제어문

java에서 코드는 위에서 아래 순으로 읽고 실행된다.

모든 일을 순차적으로 실행할 수 있다면 아무런 상관이 없겠지만, 어떤 코드를 반복해야 될 수도 있고 어떤 코드는 건너뛰는 등의 순서를 변경해야 되는 일이 발생한다.

이 때, 제어문을 사용하여 코드 실행 흐름을 제어할 수 있다.

이러한 제어문은 선택문(if-then, if-then-else, switch)과, 반복문(for, while, do-while), 분기문(break, continue, return)으로 나뉜다.

선택문(Decision-making Statement)

if-then

"돈이 있으면 택시를 타고간다"

위와 같은 상황처럼 조건을 판단해서 그 상황에 맞게 처리해야 할 경우가 생기게 된다.

이렇듯 조건을 판단하여 해당 조건에 맞는 상황을 수행하는데 쓰이는 것이 if 문이다


if(조건식) { // 한 줄일 경우 {} 생략 가능 
	조건이 참일 경우 실행되는 코드; 
}

boolean money = true;
if (money) {
    System.out.println("택시를 타고 가라");
}

if-then-else

"돈이 있으면 택시를 타고 가고 돈이 없으면 걸어 간다."

기본적인 if-then 문에서는 참일 경우만 실행이 됬다면, if-then-else 문은 거짓일 때도 실행할 수 있다.

즉 조건식이 참일 경우와 거짓일 경우의 실행되는 코드들을 나눌 수 있음


if(조건식) { 
	참일 경우; 
} else { 
	거짓일 경우; 
}

boolean money = true;
if (money) {
    System.out.println("택시를 타고 가라");
}else {
    System.out.println("걸어가라");
}

조건문을 테스트 하면서 참이면 if문에 속한 문장들을 수행하고 조건문이 거짓이면 else문에 속한 문장들을 수행한다.

조건들이 한 개만 있을 수도 있지만, 여러가지 조건을 사용해야 할 경우 else if() 를 사용하여 또 다른 조건식을 사용할 수 있다.

switch

switch/case 문은 if 문과 비슷하지만 좀 더 정형화된 조건 판단문 이다.

switch(입력변수) {
    case 입력값1: ...
         break;
    case 입력값2: ...
         break;
    ...
    default: ...
         break;
}

입력변수의 값과 일치하는 case 입력값 (입력값1, 입력값2,...) 이 있다면 해당 case문에 속한 문장들이 실행된다.

case문마다 break 라는 문장이 있는데 해당 case문을 실행한 뒤 switch 문을 빠져나가기 위한 것이다.

만약 break 문이 빠져 있다면 그 다음의 case 문이 실행된다.


public class Sample {
    public static void main(String[] args) {
        int month = 8;
        String monthString = "";
        switch (month) {
            case 1:  monthString = "January";
                     break;
            case 2:  monthString = "February";
                     break;
            case 3:  monthString = "March";
                     break;
            case 4:  monthString = "April";
                     break;
            case 5:  monthString = "May";
                     break;
            case 6:  monthString = "June";
                     break;
            case 7:  monthString = "July";
                     break;
            case 8:  monthString = "August";
                     break;
            case 9:  monthString = "September";
                     break;
            case 10: monthString = "October";
                     break;
            case 11: monthString = "November";
                     break;
            case 12: monthString = "December";
                     break;
            default: monthString = "Invalid month";
                     break;
        }
        System.out.println(monthString);
    }
}

switch 문의 입력이 1이면 "January" 라는 문자열이, 12면 "December" 라는 문자열이 출력된다.

위의 예제는 month가 8로 고정되어 있기 때문에 "August" 라는 문자열이 출력될 것이다.

위 switch문은 month의 값이 1이면 case 1: 문장이 실행되고 2이면 case 2: 문장이, 3이면 case 3: ... 이런식으로 수행되게 된다. 만약 month에 1에서 12사이의 숫자가 아닌 다른 값이 저장되어 있다면 default: 문장이 수행된다.

위와 같이 입력값이 정형화되어 있는 경우 if문보다는 switch/case문을 쓰는것이 가독성에서 좀 더 유리하다.

switch/case문은 if else 구조로 변경이 가능하지만 if else 구조로 작성된 모든 코드를 switch 문으로 변경할 수는 없다.

반복문(Looping Statement)

while

문장을 반혹해서 수행해야 할 경우에 사용

기본구조)

while (조건문) {
    <수행할 문장1>;
    <수행할 문장2>;
    <수행할 문장3>;
    ...
}

조건문이 참인 동안 while문의 수행할 문장들을 반복하여 수행한다.

예)

"열 번 찍어 안 넘어 가는 나무 없다" 라는 속담을 자바로 코딩하면 이렇게 된다.

int treeHit = 0;
while (treeHit < 10) {
    treeHit++;
    System.out.println("나무를  " + treeHit + "번 찍었습니다.");
    if (treeHit == 10) {
        System.out.println("나무 넘어갑니다.");
    }
}

나무를  1번 찍었습니다.
나무를  2번 찍었습니다.
나무를  3번 찍었습니다.
나무를  4번 찍었습니다.
나무를  5번 찍었습니다.
나무를  6번 찍었습니다.
나무를  7번 찍었습니다.
나무를  8번 찍었습니다.
나무를  9번 찍었습니다.
나무를  10번 찍었습니다.
나무 넘어갑니다.

위의 예에서 while문의 조건문은 treeHit < 10이다.

즉, treeHit가 10보다 작은 동안에 while 문 안의 문장들을 계속 수행한다.

whlie문 안의 문장을 보면 제일 먼저 treeHit++로 treeHit값이 계속 1씩 증가한다.

그리고 나무를 treeHit번 만큼 찍었음을 알리는 문장을 출력하고 treeHit가 10이 되면 “나무 넘어갑니다”라는 문장을 출력하고 treeHit < 10라는 조건문이 거짓이 되어 while문을 빠져 나가게 된다.

무한루프

무한루프는 무한이 반복한다는 의미인데, 자바에서 while문으로 구현할 수 있다.

while (true) {    
    <수행할 문장1>;
    <수행할 문장2>;
    ...
}

while 조건문이 true 이므로 조건문은 항상 참이 된다.

while은 조건문이 참인 동안에 while에 속해 있는 문장들을 계속해서 수행하므로 위의 예는 무한하게 while 문 내의 문장들을 수행한다.

while문 빠져 나가기(break)

강제로 while 문을 빠져나가야 할 때도 있는데 그 시점에 사용하는 것이 break 이다.

int coffee = 10;
int money = 300;

while (money > 0) {
    System.out.println("돈을 받았으니 커피를 줍니다.");
    coffee--;
    System.out.println("남은 커피의 양은 " + coffee + "입니다.");
    if (coffee == 0) {
        System.out.println("커피가 다 떨어졌습니다. 판매를 중지합니다.");
        break;
    }
}

money가 300으로 고정되어 있으니까 while (money > 0)에서 money는 0보다 크기 때문에 항상 참이다.

따라서 무한 루프를 돌게 된다.

그리고 while문이 수행되면 coffee--에 의해서 coffee의 개수가 한 개씩 줄어들게 된다.

만약 coffee가 0이 되면 if (coffee == 0) 문장이 참이 되므로 break가 호출되어 while문을 빠져 나간다

while문 조건문으로 돌아가기(continue)

while문 안의 문장을 수행할 때 어떤 조건을 검사해서 조건에 맞지 않는 경우 while문을 빠져나가는 대신 while문의 맨 처음(조건문) 돌아가게 하는 경우도 있다.

int a = 0;
while (a < 10) {
    a++;
    if (a % 2 == 0) {
        continue;  // 짝수인 경우 조건문으로 돌아간다.
    }
    System.out.println(a);  // 홀수만 출력된다.
}

위의 예는 1부터 10까지의 수 중 홀수만을 출력하는 예이다.

a가 10보다 작은 동안 a는 1만큼씩 계속 증가한다. if (a % 2 == 0) (2로 나누었을 때 나머지가 0인 경우)이 참이 되는 경우는 a가 짝수일 때이다.

즉, a가 짝수이면 continue 문장이 수행된다.

이 continue문은 while문의 맨 처음(조건문: a<10)으로 돌아가게 하는 명령어이다.

따라서 위의 예에서 a가 짝수이면 System.out.println(a)는 수행되지 않기 때문에 홀수만 출력될 것이다.

for

while문과 동일하게 문장을 반복해서 수행해야 할 경우에 사용한다.

for (초기치; 조건문; 증가치) {
    ...
}


String[] numbers = {"one", "two", "three"};
for(int i=0; i<numbers.length; i++) {
    System.out.println(numbers[i]);
}

// one
// two
// three

위 예제로 봤을때 초기치는 int i = 0이 되고 조건문은 i<numbers.length 그리고 증가치는 i++ 가 된다.

즉 i값이 numbers의 갯수보다 작은 동안 계속 i값을 1씩 증가시킨다는 의미이다.

while문과 비슷하지만 느낌상 잘 짜여진 느낌이 나는것이 for문의 매력이라고 한다.

그래서 출력은 배열안에 있는 값들이 나온다.

예제)

int[] marks = {90, 25, 67, 45, 80};
for(int i=0; i<marks.length; i++) {
    if (marks[i] >= 60) {
        System.out.println((i+1)+"번 학생은 합격입니다.");
    }else {
        System.out.println((i+1)+"번 학생은 불합격입니다.");
    }
}

값이 1씩 증가하며 for문 안의 문장들이 수행된다. 따라서 marks[i]는 차례로 90, 25, 67, 45, 80의 값을 갖게 된다. marks[i]가 60 이상이면 합격 메시지를 출력하고 60을 넘지 않으면 불합격 메시지를 출력한다. i가 marks의 갯수인 5보다 크게되면 for문이 중지됨.

for와 continue

while 문에서 보았던 continue가 for 문에도 동일하게 적용된다.

즉, for문 안의 문장을 수행하는 도중에 continue문을 만나면 for 문의 처음으로 돌아간다.

int[] marks = {90, 25, 67, 45, 80};
for(int i=0; i<marks.length; i++) {
    if (marks[i] < 60) {
        continue;
    }
    System.out.println((i+1)+"번 학생 축하합니다. 합격입니다.");
}

점수가 60점 미만인 학생일 경우에는 marks[i] < 60이 참이 되어 continue문이 수행된다.

따라서 축하 메시지를 출력하는 부분을 수행하지 않고 for문의 첫부분으로 돌아가게 된다.

※ while 문과 마찬가지로 for 문안에서 break 문장을 만나면 for 문을 벗어난다.

이중 for 문

for 문을 두 번 이용한 구구단 출력 예제

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

위의 예를 보면 for 문을 두번 사용 하였다.

먼저 2부터 9까지의 숫자가 차례로 i에 대입된다.

i가 처음 2일 때 다시 for 문을 만나게 된다.

이제 1부터 9까지의 숫자가 j에 대입되고 그 다음 문장인 System.out.print(ij+" ");를 수행한다.
따라서 i가 2일 때 2
1, 22, 23, , , ,2*9 까지 차례로 수행되며 그 값을 출력하게 된다.

그 다음 i가 9일 때가지 반복하게 된다.

for each 문

for each는 J2SE 5.0 부터 추가되었다.

for each 라는 키워드가 따로 있는 것은 아니고 동일한 for를 이용한다.

하지만 조건식 부분의 문법이 조금 다르다.

기존 for문

String[] numbers = {"one", "two", "three"};
for(int i=0; i<numbers.length; i++) {
    System.out.println(numbers[i]);
}

for each 구조로 변경

String[] numbers = {"one", "two", "three"};
for(String number: numbers) {
    System.out.println(number);
}

for each 문이 좀 더 직관적으로 보인다.

for each 문 구조

for (type var: iterate) {
    body-of-loop
}

여기서 iterate는 루프를 돌릴 객체이고 iterate 객체에서 한개씩 순차적으로var에 대입되어 for문이 수행된다.

iterate로 사용할 수 있는 자료형은 루프를 돌릴 수 있는 자료형(배열 및 ArrayList등) 만 가능..

ArrayList를 이용한 for each

import java.util.ArrayList;
import java.util.Arrays;

public class Sample {
    public static void main(String[] args) {
        ArrayList<String> numbers = new ArrayList<>(Arrays.asList("one", "two", "three"));
        for (String number : numbers) {
            System.out.println(number);
        }
    }
}

하지만 for each 문은 따로 반복회수를 명식적으로 주는 것이 불가능 하다.

1스탭씩 순차적으로 반복될때만 사용가능하다는 제약이 있다.

출처:

[Java] 자바 기본 제어문 - 선택문, 반복문
점프 투 자바 ifans

profile
"한 명이 걷는 천 걸음 보다 천 명이 함께 걷는 한 걸음이 성공의 시작이고 완성이다"

0개의 댓글