ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 4. 자바 배열과 반복문 (2) 반복문
    자바(Java) 강의 2019. 3. 9. 13:05


    예상 독자

    목표

    • 반복문이 필요한 이유
    • for 반복문
    아래의 코드를 먼저 실행 해 보자.


    public class
    Main {
    public static void main(String[] args) {
    int[] integers = new int[]{ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
    System.out.println(integers[0]);
    System.out.println(integers[1]);
    System.out.println(integers[2]);
    System.out.println(integers[3]);
    System.out.println(integers[4]);
    System.out.println(integers[5]);
    System.out.println(integers[6]);
    System.out.println(integers[7]);
    System.out.println(integers[8]);
    System.out.println(integers[9]);

    }
    } 실행 결과: 10 20 30 40 50 60 70 80 90 100

    뭔가 전 포스트의 첫 부분에서 느꼈던 심란함이 돌아오는 것 같지 않은가? 이 코드를 보고 심란하지 않다면 1부터 100까지 저장하는 int배열을 만들고 그 값을 하나하나 출력 해 보라. 그것도 힘들지 않고 할만하다면 1부터 1000까지 저장하는 배열을 만들고 그 값을 하나하나 출력 해 보라. 마음이 심란 해 질 때까지 값을 늘려 System.out.println을 복사/붙여넣기 해 보고 다음으로 넘어가도록 하자.

    반복문이 필요한 이유

    나는 참을성이 없는 사람이라 System.out.println를 10개만 복사/붙여넣기 했는데도 화가 났다. 만약에 이런 작업을 100개 1000개 해야 된다면 굉장히 힘들 것이다. 다행히 대부분의 프로그래밍 언어는 반복문이라는 것을 제공한다. 반복문을 이용하면 이렇게 복사 붙여넣기 하는 수고를 덜 수 있다.

    System.out.println(integers[0]); // 이 줄의 인덱스 0, 다음 줄의 인덱스 = (이 줄의 인덱스) + 1 -> 1
    System.out.println(integers[1]); // 이 줄의 인덱스 1, 다음 줄의 인덱스 = (이 줄의 인덱스) + 1 -> 2
    System.out.println(integers[2]); // 이 줄의 인덱스 2, 다음 줄의 인덱스 = (이 줄의 인덱스) + 1 -> 3
    System.out.println(integers[3]); // 이 줄의 인덱스 3, 다음 줄의 인덱스 = (이 줄의 인덱스) + 1 -> 4
    System.out.println(integers[4]); // 이 줄의 인덱스 4, 다음 줄의 인덱스 = (이 줄의 인덱스) + 1 -> 5
    System.out.println(integers[5]); // 이 줄의 인덱스 5, 다음 줄의 인덱스 = (이 줄의 인덱스) + 1 -> 6
    System.out.println(integers[6]); // 이 줄의 인덱스 6, 다음 줄의 인덱스 = (이 줄의 인덱스) + 1 -> 7
    System.out.println(integers[7]); // 이 줄의 인덱스 7, 다음 줄의 인덱스 = (이 줄의 인덱스) + 1 -> 8
    System.out.println(integers[8]); // 이 줄의 인덱스 8, 다음 줄의 인덱스 = (이 줄의 인덱스) + 1 -> 9
    System.out.println(integers[9]); // 이 줄의 인덱스 9, 다음 줄의 인덱스 = (이 줄의 인덱스) + 1 -> 10

    위의 코드에서 이 부분을 보자. 딱 하나 빼고 모든것이 반복된다. 그 하나가 무엇인가? 바로 인덱스이다. 한 줄, 한 줄, 여러분 복사 붙여넣기 하면서 뭘 느꼈나? 무엇을 수정했나? System.out.println(integers[0]); 복사 -> 붙여넣기 후 0을 1로 고쳤을 것이다. 그리고 같은 작업을 그 다음줄에 한 후 인덱스를 2로 고쳤을 것이다. 여러분은 0에서 부터 시작하여, 다음 줄에 System.out.println을 하나 복사 붙여넣기 할 때 마다 윗 줄의 인덱스에 1을 더한 값으로 현재 줄의 인덱스를 고쳤다. 그리고 이를 0~9까지 10번 실행했다. 그렇다면 0, 1, 2, 3, .. 9 이렇게 쓰지 말고 변수를 쓰는건 어떨까?

    public class Main {
    public static void main(String[] args) {
    int[] integers = new int[]{ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
    int index = 0;
    System.out.println(integers[index]);
    index = index + 1; // index = 0 + 1
    System.out.println(integers[index]);
    index = index + 1; // index = 1 + 1
    System.out.println(integers[index]);
    index = index + 1; // index = 2 + 1
    System.out.println(integers[index]);
    index = index + 1; // index = 3 + 1
    System.out.println(integers[index]);
    index = index + 1; // index = 4 + 1
    System.out.println(integers[index]);
    index = index + 1; // index = 5 + 1
    System.out.println(integers[index]);
    index = index + 1; // index = 6 + 1
    System.out.println(integers[index]);
    index = index + 1; // index = 7 + 1
    System.out.println(integers[index]);
    index = index + 1; // index = 8 + 1
    System.out.println(integers[index]);

    index = index + 1; // index = 9 + 1 : 10이니까 이제 그만 복붙 해도 됨

    }
    } 실행 결과: 10 20 30 40 50 60 70 80 90 100

    위와 같이 하면 우리는 0, 1, 2, 3하고 줄마다 인덱스를 하나하나 수정 하는 대신 int index=0; 선언 후 아래의 코드를 10번 복사 붙여넣기 할 수 있다.

    System.out.println(integers[index]);
    index = index + 1; // index에 기존의 index + 1을 새로 저장하라.

    참고! index = index + 1;이 뭔지 헷갈리는가? 이것은 그냥 index + 1을 계산 한 값을 index에 다시 넣으라는 뜻이다. 예를들어 원래 index가 10이었다고 치자. index = index + 1;은 index = 10 + 1이므로 이 줄 실행 후의 index의 값은 11이 된다. 

    위의 코드를 분석 해 보자. 일단 우리는 index = 0에서 시작했다. 왜냐하면 배열이 0에서 시작하기 때문이다. 그리고 System.out.println(integers[index]); 와 index = index +1;을 복사/붙여넣기 했다. 몇번 했는가? 10번했다. 왜 10번 했는가? 배열의 길이가 10이기 때문이었다. 이를 체계화 해보자.

    1. index = 0으로 초기화 한다.

    2. System.out.println(integers[index]); 와 index = index +1;를 복사 붙여넣기 한다.

    3. 새로 계산된 index가 0에서 10사이이면 2번으로 돌아간다. 그게 아니라면 10번을 채운 것이므로 복/붙을 그만한다.

    위와 같은 로직을 마음대로 번역 해 보면 아마 아래와 같을 것이다.

    (index 가 0에서 integers.length사이인 ) 동안 {
    System.out.println(integers[index]);
    index = index + 1;
    }

    '동안'을 영어로 번역 해 보자. 영어이기 때문에 어순이 바뀐다!

    for (index 가 0에서 integers.length사이)  {
    System.out.println(integers[index]);
    index = index + 1;
    }

    index가 0에서 integers.length사이는 다시 말해 index가 integers.length보다 작을 때 까지로 해석 할 수 있다. 

    for (시작 index = 0이고; index < integers.length;) {
    System.out.println(integers[index]);
    index = index + 1;
    }

    자 아래는 실제 자바의 for문 문법이다. 위에서 우리가 브레인스토밍 했던 것과 많이 다르지 않음을 알 수 있다.

    public class Main {
    public static void main(String[] args) {
    int[] integers = new int[]{ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
    for (int index = 0; index < integers.length;) {
    System.out.println(integers[index]);
    index = index + 1;
    }
    }
    } 실행 결과: 10 20 30 40 50 60 70 80 90 100

    index = index + 1; 대신에 index++를 사용 할 수 있다. 같은 뜻인데 좀 더 간편한 버전이다.

    public class Main {
    public static void main(String[] args) {
    int[] integers = new int[]{ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
    for (int index = 0; index < integers.length;) {
    System.out.println(integers[index]);
    index++; // index = index + 1; 과 똑같은 문법
    }
    }
    } 실행 결과: 10 20 30 40 50 60 70 80 90 100

    위의 문법은 아래와 똑같다. 아래를 보자. 바뀐게 무엇인가? index++의 위치이다. 위와 아래는 정확히 같은 일을 수행한다. index++이 비록 System.out.println보다 위에 있지만 실행 할 때는 index++이 중괄호의 마지막에서 실행된다고 생각하면 된다. 위의 예는 이해를 돕기 위해 작성 한 것이고, 실제로는 대부분 아래 같은 구조로 사용한다.

    public class Main {
    public static void main(String[] args) {
    int[] integers = new int[]{ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
    for (int index = 0; index < integers.length; index++) { // <- 이런 구조 (시작; 반복 조건; ++)
    System.out.println(integers[index]);
    }
    }
    }

    항상 배열의 길이만큼만 반복해야 하는가? 그렇지 않다. index가 배열의 길이보다 작기만 하면 어느 범위이든 상관 없다. software 문자 배열로 다시 실습 해 보자.

    public class Main {
    public static void main(String[] args) {
    char[] str = new char[]{'s','o','f','t','w','a','r','e'};

    for(int i = 0; i < str.length; i++) {
    System.out.println(str[i]);
    }
    }
    } 실행 결과: s o f t w a r e

    자 이 코드를 가지고 연습을 해보자. soft만 출력하려면 어떻게 해야겠는가? 그렇다 배열의 인덱스 중 0, 1, 2, 3만 출력하면 된다. 이는 어떻게 하는가? 마지막 값을 보자 3은 4보다 작다. 그러므로 아래처럼 표현 할 수 있다.

    public class Main {
    public static void main(String[] args) {
    char[] str = new char[]{'s','o','f','t','w','a','r','e'};

    for(int i = 0; i < 4; i++) {
    System.out.println(str[i]);
    }
    }
    }

    실행 결과: s o f t

    또는 작거나 같다 기호를 사용 할 수도 있다.

    public class Main {
    public static void main(String[] args) {
    char[] str = new char[]{'s','o','f','t','w','a','r','e'};

    for(int i = 0; i <= 3; i++) {
    System.out.println(str[i]);
    }
    }
    }

    실행 결과: s o f t

    만약 f, t, w, a, r만 출력하고 싶다면 어떻게 할 것인가? 인덱스를 보자, 2, 3, 4, 5 즉 시작은 2에서 하고 끝을 5에서 맺는다.

    public class Main {
    public static void main(String[] args) {
    char[] str = new char[]{'s','o','f','t','w','a','r','e'};

    for(int i = 2; i < 6; i++) { // 또는 i <= 5
    System.out.println(str[i]);
    }
    }
    }

    실행 결과: f t w a


    만약 s, f, w, r만 출력하고 싶다면 어떻게 할 것인가? s, f, w, r의 인덱스를 보자 0, 2, 4, 6 즉 인덱스가 2씩 증가 하는 것을 확인 할 수 있다.

    public class Main {
    public static void main(String[] args) {
    char[] str = new char[]{'s','o','f','t','w','a','r','e'};

    for(int i = 0; i < str.length; i = i + 2) {
    System.out.println(str[i]);
    }
    }
    }

    실행 결과: s f w r

    위와 같은 실습으로 우리는 다음과 같이 for문의 문법적 요소를 파악 할 수 있다.

    for 반복문 

    이제 진짜로 반복문에 대해 설명하겠다. 반복문은 다섯가지 요소로 구성된다. 위의 그림을 예로 설명하겠다. 아래는 위에서 했던 정수형 배열 코드이다.

    public class Main {
    public static void main(String[] args) {
    int[] integers = new int[]{ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
    for (int index = 0; index < integers.length; index++) {

    System.out.println(integers[index]);
    }
    }
    }

    1. 키워드 for : 반복문이 시작됨을 알린다.
    2. int index = 0; : 조건으로 사용 할 변수. 보통 배열의 인덱스 값이 오지만 항상 그런건 아니다.
    3. index < integers.length; : 이부분은 논리식이 들어가는 부분이다 index == 0, index >= x, 등등 논리식이기만 하면 뭐든 상관 없다. 이 논리식이 true이면 중괄호 내부를 실행하고 아니면 반복문을 종료한다.
    4. index++ : 중괄호 실행 후 실행하는 구문이다. 꼭 index++일 필요는 없다. index = index + 1, index = index - 1, index-- (index++의 반대), 아니면 index가 아닌 아얘 다른게(예를들면 메서드 콜) 들어가도 된다. 
    5. {} 중괄호 : 반복문의 논리식이 true일 때 실행 할 로직을 담고있다.
    다이어그램으로 보면 다음과 같다.

    처음 for문으로 진입하면 일단 첫번째 세미콜론부분을 실행한다. 위의 예에서는 int index = 0; 이라는 구문을 실행한다. 즉 index라는 변수를 선언하고 값 0을 할당 한 것이다. 그 다음에는 두번째 세미콜론 부분인 index < integers.length를 검사한다. 현재 index 는 0이고 integers.length는 10이므로 0 < 10 -> true이다. 따라서 반복문의 중괄호 내부를 실행한다. 실행을 마친 후 반복문은 마지막 부분인 index++을 실행한다. 그리고 다시 두번째 세미콜론인 조건 부분으로 돌아가 조건 검사부터 반복한다.

    한가지 덧붙여 말하면 위의 스텝 중 2, 3, 4는 반드시 필요한건 아니다. 무슨 뜻인가?
    for(; ;) {
    System.out.println("이것은 무한루프.");
    }

    위처럼 아무 조건도 넣어주지 않으면 무한루프를 만들어 줄 수 있다. for문을 위처럼 사용하는 경우는 매우 드무니 이해가 안되면 넘어가도록 하자. for문을 많이 사용하다보면 결국 이해 될 것이다.

    반복문에 대해 아직 할 말이 많지만, 너무 길어져 여기서 잠시 끊도록 하겠다. 다음 포스트에서는 for문을 이어서 여러가지 연습 문제를 풀어보도록 하겠다. 조건문과 반복문을 알면 이제 어떤 프로그램이든 짤 수 있다.

    연습문제: 

    아래의 코드를 수정 해 보자. 해당 배열을 처음부터 끝까지 반복하면서, 배열의 값이 50보다 작거나 같으면 "50보다 작거나 같다."를 출력, 50보다 크면 "50보다 크다."를 출력한다. (힌트: 반복문 중괄호 안에서 조건문을 사용해라.)

    public class Main {
    public static void main(String[] args) {
    int[] integers = new int[]{ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
    for (int index = 0; index < integers.length; index++) {

    System.out.println(integers[index]);
    }
    }
    }

    실행 결과는 다음과 같아야 한다.

    50보다 작다.
    50보다 작다.
    50보다 작다.
    50보다 작다.
    50보다 작다.
    50보다 크다.
    50보다 크다.
    50보다 크다.
    50보다 크다.
    50보다 크다.

    여기까지 다 읽었으면 하트를 눌러라. 

    다음 포스트: 4. 자바 배열과 반복문 (3) 중첩 배열

    댓글

f.software engineer @ All Right Reserved