[4주차] 제어문

janjanee·2022년 8월 1일
0
post-thumbnail

2021.01.06 작성글 이전

4. 제어문

학습 목표 : 자바가 제공하는 제어문을 학습하세요.

제어문 : 프로그램의 흐름을 바꾸는 역할을 하는 문장

4-1. 선택문

if

만일(if) 조건식이 참(true)이면 괄호 {} 안의 문장들을 수행하라

if (조건식) {
    // 조건식이 참(true)일 때 수행될 문장
}

다음과 같이 표현할 수 있다.

int x = 0;

// 1
if (x==0) {
  System.out.println("x는 0입니다.");
}

/// 2
if (x==0) System.out.println("x는 0입니다.");

x가 0인지 판별하는 조건식이 주어지고, 블럭 내부에서 수행될 문장을 적는다.
1번과 2번은 동일한 코드이다. 수행될 문장이 한 줄일 경우에는 블럭을 생략하고 한줄로 표현할 수 있다.

if-else 문

if (조건식) {
    // 조건식이 참(true)일 때 수행될 문장
} else {
    // 조건식이 거짓(false)일 때 수행될 문장
}
int x = 0;

if (x==0) {
    System.out.println("x는 0입니다.");
} else {
    System.out.println("x는 0이 아닙니다.");
}

처음 예제와 달리 x는 0이 아닐 경우에는 else 블럭읨 문장을 수행하게 된다.

if-else if문

if-else는 두 가지중 한 가지가 수행되는 구조이다. 그렇다면 셋 이상일때 어떻게 해야할까? if-else if 문을 사용하면 된다.

if (조건식1) {
    // 조건식1이 참(true)일 때 수행될 문장
} else if (조건식2) {
    // 조건식2가 참(true)일 때 수행될 문장
} else if (조건식3) {
    // 조건식3이 참(true)일 때 수행될 문장
} else {    // 마지막에는 보통 else 블럭으로 끝나며, else 블럭은 생략 가능하다.
    // 위의 어떤 조건식도 맞지 않는 경우 수행
}

다음은 예제 코드이다.

int score = 0;
char grade = ' ';

System.out.println("점수를 입력하세요:");
Scanner scanner = new Scanner(System.in);

score = scanner.nextInt();

if (score >= 90) {
    grade = 'A';
} else if (score >= 80) {
    grade = 'B';
} else if (score >= 70) {
    grade = 'C';
} else {
    grade = 'D';
}

System.out.println("당신의 학점은 " + grade + "입니다.");

점수를 입력받아 학점을 보여주는 예제이다.
조건식 3개가 들어있는데 90점 이상일 때, 80점 이상일 때, 70점 이상일 때 그리고 그 외(else)가 있다.
예를들어, 점수가 85로 입력됐다면 학점은 'B'로 출력된다. 점수가 44로 입력됐다면 학점은 'D'로 출력된다.

중첩 if문

if문 블럭 내에 또 다른 if문을 포함시켜 중첩 if문으로 사용할 수 있다.

if (조건식1) {
    // 조건식1이 참(true)일 때 수행될 문장
    if (조건식2) {
        // 조건식1과 조건식2가 모두 참(true)일 때 수행될 문장
    } else {
        // 조건식1이 true이고, 조건식2가 false일 때 수행될 문장
    }
} else {
    // 조건식1이 false일 때 수행될 문장
}

위의 학점예제에서 A 학점인 경우 중첩if를 사용하여 +, -, 0 으로 세분화 할 수 있다.

char opt = '0';

if (score >= 90) {

    grade = 'A';

    if (score >= 98) {
        opt = '+';
    } else if (score < 94){
        opt = '-';
    }

} ...

점수가 98이라면 'A+', 95라면 'A0'의 결과가 출력된다.

switch

if 문은 조건식의 결과가 많아질수록 else-if를 계속 추가해야해서 복잡해질 수 있다.
switch문은 단 하나의 조건식으로 많은 경우의 수를 처리할 수 있고 표현도 직관적이라 알아보기 쉽다.

다만, switch문은 제약조건이 있어서, 경우의 수가 많아도 어쩔 수 없이 if문으로 작성해야 하는 경우도 있다.

switch (조건식) {
    case1 :
        // 조건식의 결과가 값1과 같을 때, 수행될 문장
        break;
    case2 :
        // 조건식의 결과가 값2와 같을 때, 수행될 문장
        break;
    ...
    default :
        // 조건식의 결과와 일치하는 case문이 없을 때 수행될 문장
}
  1. 조건식을 계산한다.

  2. 조건식의 결과와 일치하는 case문으로 이동한다.

  3. 이후의 문장들을 수행한다.

  4. break문이나 switch문이 끝나면 switch문 전체를 빠져나간다.

  5. switch문의 결과와 일치하는 case문이 없다면 마지막 default문으로 이동한다.(if문의 else와 같음)

  6. break를 생략하면 case문 끼리의 구분이 없어지므로 다른 break문을 만나거나 switch문이 끝날 때 까지

    나오는 모든 문장을 수행하므로 생략하지 않도록 주의

  7. 물론 때에 따라서는, break문을 일부러 생략하는 경우도 있음.

switch문의 제약조건

  1. switch문의 조건식 결과는 정수 또는 문자열이어야 한다.
  2. case문의 값은 정수, 상수, 문자열이 가능하며 중복되지 않아야 한다.
switch (month) {
    case 3: case 4: case 5:
        System.out.println("봄");
        break;
    case 6: case 7: case 8:
        System.out.println("여름");
        break;
    case 9: case 10: case 11:
        System.out.println("가을");
        break;
    case 12: case 1: case 2:
        System.out.println("겨울");
        break;
    default:
        System.out.println(month + "은(는) 월이 아닙니다.");
}

월에 따라 어떤 계절인지 확인하는 간단한 예제이다.

  • switch문도 if 처럼 중첩 switch문이 가능하다.

4-2. 반복문

어떤 작업이 반복적으로 수행되도록 할 때 사용

for문

반복 횟수를 알고 있을 때 적합하다.

for(초기화;조건식;증감식) {
    // 조건식이 참일 때 수행될 문장들
}
for (int i=1; i<=5; i++) {
    System.out.println("I love code.");
}

위위 예제를 풀어보면 변수 i에 1을 저장 후, 반복마다 i의 값을 1씩 증가시킨다.
그러다 i의 값이 5를 넘으면 조건식 'i<=5'가 거짓(false)가 되어 반복을 마친다.

초기화

반복문에 사용될 변수를 초기화하는 부분이며 처음에 한번만 수행된다.
보통은 변수 하나지만, 둘 이상의 변수가 필요할 때는 ',' 콤마를 구분자로 초기화한다.

for(int i=1, j=0; i<=10; i++) { ... }

조건식

조건식 값이 참이면 반복을 계속하고, 거짓이되면 반복을 중단하여 for문을 빠져나온다.

증감식

반복문을 제어하는 변수의 값을 증가 또는 감소시킨다. 증감식도 ',' 콤마를 이용해서 두 문장 이상을 하나로 연결해서 사용 가능하다.

for(int i=1, j=10; i<=10; i++, j--) { ... }

중첩 for문

for문 안에 또 다른 for문을 넣어 중첩할 수 있다.

int line;

System.out.println("*을 출력할 라인의 수를 입력하세요.");
Scanner scanner = new Scanner(System.in);
line = scanner.nextInt();

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

// 결과

*을 출력할 라인의 수를 입력하세요.
10
*
**
***
****
*****
******
*******
********
*********
**********

중첩 for문의 단골 예제인 별 찍기 구조를 만드는 예제이다.

향상된 for문(enhanced for statement)

JDK1.5 부터 배열과 컬렉션에 저장된 요소에 접근할 때 더 편리한 방법으로 처리할 수 있도록 제공됨.

for (타입 변수명 : 배열 또는 컬렉션) {
    // 반복할 문장
}
int [] arr = {10, 20, 30, 40, 50};
int sum = 0;

//1 
for(int i=0; i<arr.length; i++) {
    sum += arr[i];
}

System.out.println(sum);

sum = 0;

// 2 
for (int i : arr) {
    sum += i;
}

System.out.println(sum);

// 결과
150
150

1번 코드랑 2번 코드는 동일하다. 배열이나 컬렉션 요소인 경우는 2번의 향상된 for문을 사용하면 더 간결한 코드를 만들 수 있다.

while문

while (조건식) {
    // 조건식의 결과가 참(true)인 동안, 반복될 문장
}
  1. 조건식이 참이면 블럭{}을 수행하고, 거짓이면 while문을 빠져나간다.
  2. 블럭{}의 문장을 수행하고 다시 조건식으로 돌아간다.

for문과 while문의 비교

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

// 2
int i = 1;

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

1번과 2번 두 코드는 완전 동일하다.

int num;
int sum = 0;
boolean flag = true;
Scanner scanner = new Scanner(System.in);

System.out.println("합계를 구할 숫자를 입력하세요.(끝내려면 0을 입력)");

while (flag) {
    System.out.printf(">>");

    num = scanner.nextInt();

    if (num != 0) {
        sum += num;
    } else {
        flag = false;
    }
}

System.out.println("합: " + sum);

while문을 사용한 예제이다. 사용자가 0을 입력하여 종료하기 전까지 flag 상태가 true 여서 무한반복을 한다.
사용자가 0을 입력하면 flag값이 false가 되면서 while문을 빠져나온다.

do-while문

while문의 변형으로, 기본적인 구조는 같으나 조건식과 블럭{}의 순서를 바꿔놓은 것

do {
    // 조건식의 결과가 참일 때 수행될 문장
} while (조건식);   // 끝에 ';'을 잊지 않도록 주의

while과의 차이점이라면 while문은 조건식의 결과에 따라서 블럭 부분이 한 번도 수행되지 않을 수 있지만
do-while은 최소한 한번은 수행되는 차이점이 있다.

그리 자주 사용되지 않는다.

break문

break문은 자신이 포함된 가장 가까운 반복문을 벗어난다.

주로 if 문과 함께 사용되어 특정 조건을 만족하면 반복문을 벗어나도록 제어한다.

int sum = 0;
int i = 0;

while (true) {
    if (sum > 100) {
        break;
    }

    ++i;
    sum += i;
}

위 코드는 sum이 100을 넘으면 break 문을 만나서 반복문인 while을 벗어난다.
당연히 break문을 만나서 while을 벗어날 때 아래의 ++i, sum+=i;sms 수행되지 않는다.

continue 문

반복문 내에서 사용가능하며 반복이 진행되는 도중 continue문을 만나면 다음 반복으로 넘어간다.

  • for문의 경우 다음 증감식으로 이동하며, while과 do-while의 경우 조건식으로 이동한다.
  • 특정조건을 만족하는 경우를 제외하고 반복하고 싶은 경우에 유용하다.
for (int i = 1; i <= 10; i++) {

    if (i % 2 == 0) {
        continue;
    }

    System.out.println(i);

}

// 결과
1
3
5
7
9

위의 코드는 짝수일 경우 continue문을 만나서 다음 증감식으로 이동하여 홀수인 결과만 출력한다.

4-3. 과제 (옵션)

과제 1. live-study 대시 보드를 만드는 코드를 작성하세요.

  • 깃헙 이슈 1번부터 18번까지 댓글을 순회하며 댓글을 남긴 사용자를 체크 할 것.

  • 참여율을 계산하세요. 총 18회에 중에 몇 %를 참여했는지 소숫점 두자리가지 보여줄 것.

  • Github 자바 라이브러리를 사용하면 편리합니다.

  • 깃헙 API를 익명으로 호출하는데 제한이 있기 때문에 본인의 깃헙 프로젝트에 이슈를 만들고 테스트를 하시면

    더 자주 테스트할 수 있습니다.

과제1 코드 링크

과제 2. LinkedList를 구현하세요.

  • LinkedList에 대해 공부하세요.
  • 정수를 저장하는 ListNode 클래스를 구현하세요.
  • ListNode add(ListNode head, ListNode nodeToAdd, int position)를 구현하세요.
  • ListNode remove(ListNode head, int positionToRemove)를 구현하세요.
  • boolean contains(ListNode head, ListNode nodeTocheck)를 구현하세요.

과제2 코드 링크

과제2 테스트 링크

과제 3. Stack을 구현하세요.

  • int 배열을 사용해서 정수를 저장하는 Stack을 구현하세요.
  • void push(int data)를 구현하세요.
  • int pop()을 구현하세요.

과제3 코드 링크

과제3 테스트 링크

과제 4. 앞서 만든 ListNode를 사용해서 Stack을 구현하세요.

  • ListNode head를 가지고 있는 ListNodeStack 클래스를 구현하세요.
  • void push(int data)를 구현하세요.
  • int pop()을 구현하세요.

과제4 코드 링크

과제4 테스트 링크

과제 5. Queue를 구현하세요.

  • 배열을 사용해서 한번
  • ListNode를 사용해서 한번.

과제5 배열 Queue 코드 링크

과제5 배열 Queue 테스트 링크

과제5 배열 Queue 코드 링크

과제5 배열 Queue 테스트 링크

References

  • 남궁성, 『자바의 정석』, 도우출판(2016)
  • 신용권, 『이것이 자바다』, 한빛미디어(2018)
  • Bohyoh Shibata, 『자료구조와 함께 배우는 알고리즘 입문』, 이지스퍼블리싱(2018)
  • LinkedList
profile
얍얍 개발 펀치

0개의 댓글