2) 반복문

· for 문

 

for문은 예제를 통해서 알아보는 것이 가장 쉽다. 예제를 따라해 보도록 하자.

 

예 1) 전형적인 for문


String[] numbers = {"one", "two", "three"};

for(int i=0; i

     System.out.println(numbers[i]);

}


 

결과는 다음과 같다.

 


one

two

three


numbers라는 배열의 첫번째 요소부터 마지막 요소까지 출력하는 예이다.

for의 조건문은 세미콜론(;)을 구분자로 세 부분으로 나뉘어진다.

 


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

위 예에서 초기치는 i=0이 되고 조건문은 i


 

for문의 쓰임새를 알기 위해서 다음을 가정해 보자.

 

“총 5명의 학생이 시험을 보았는데 시험점수가 60점이 넘으면 합격이고 그렇지 않으면 불합격이다. 합격인지 불합격인지에 대한 결과를 보여준다.”

우선 5명의 학생의 시험성적을 다음과 같이 표현 해 보았다.

 


int[] marks = {90, 25, 67, 45, 80};


 

1번 학생은 90점이고 5번 학생은 80점이다.

이런 점수를 차례로 검사해서 합격했는지 불합격했는지에 대한 통보를 해주는 프로그램을 만들어 보자.

 


int[] marks = {90, 25, 67, 45, 80};

for(int i=0; i

     if (marks[i] >= 60) {

          System.out.println((i+1)+"번 학생은 합격입니다.");

     }else {

          System.out.println((i+1)+"번 학생은 불합격입니다.");

     }

}


 

i값이 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문의 처음으로 돌아가게 된다.

위의 예제를 그대로 이용해서 60점 이상인 사람에게는 축하 메시지를 보내고 나머지 사람에게는 아무런 메시지도 전하지 않는 프로그램을 만들어 보자.

 


int[] marks = {90, 25, 67, 45, 80};

for(int i=0; i

      if (marks[i] < 60) {

            continue;

      }

      System.out.println((i+1)+"번 학생 축하합니다. 합격입니다.");

}


점수가 60점 미만인 학생일 경우에는 marks[i] < 60이 참이 되어 continue문이 수행된다. 따라서 축하 메시지를 출력하는 부분을 수행하지 않고 for문의 첫부분으로 돌아가게 된다.

 

· for each문

 

for each는 J2SE 5.0 부터 추가되었다. for each 라는 키워드가 따로 있는 것은 아니고 동일한 for를 이용한다. 하지만 조건식 부분이 조금 다르다. 보통 다른 언어에서 for each 라고 많이 하므로 자바에서도 보통 for each문이라고 말한다.

다음은 이전에 공부했던 평범한 for 문장이다.

 


String[] numbers = {"one", "two", "three"};

for(int i=0; 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등이 가능하다.

따로 반복회수를 임의로 주는 형태가 아니라면 for each를 이용해서 훨씬 간단하게 작성할 수 있다. 루프를 핸들링할 수는 없기 때문에 1스탭씩 순차적으로 반복할때만 사용가능하다는 제약이 있다.

 

· while문

 

반복해서 문장을 수행해야 할 경우 while문을 사용한다.

 

다음은 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문을 빠져 나가게 된다.

여기서 treeHit++ 는 프로그래밍을 할 때 매우 자주 쓰이는 기법으로 treeHit의 값을 1만큼씩 증가시킬 목적으로 쓰이는 것이다. 이것은 treeHit += 1처럼 쓰기도 한다.

 

· 무한루프(Loop)

 

이번에는 무한루프에 대해서 알아보기로 하자. 무한 루프라 함은 무한히 반복한다는 의미이다. 자바에서 무한루프는 while문으로 구현 할 수가 있다. 우리가 사용하는 프로그램들 중에서 이 무한루프의 개념을 사용하지 않는 프로그램은 하나도 없을 정도로 이 무한루프는 자주 사용된다. 다음은 무한루프의 기본적인 형태이다.

 


while (true) {

<수행할 문장1>

<수행할 문장2>

...

}


 

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

다음의 예를 보자.

 


while (true) {

     System.out.println("Ctrl-C를 눌러야 while문을 빠져 나갈 수 있습니다.");

}


다음과 같은 문장이 출력된다.

 


Ctrl-C를 눌러야 while문을 빠져 나갈 수 있습니다.

Ctrl-C를 눌러야 while문을 빠져 나갈 수 있습니다.

...


 

위의 문장이 영원히 출력될 것이다. Ctrl-C를 눌러서 빠져 나가도록 하자(이클립스에서는 "중지" 버튼을 클릭하자).

 

· while문 빠져 나가기(break)

 

while 문은 조건문이 참인 동안 계속해서 while문 안의 내용을 수행하게 된다. 하지만 강제로 while문을 빠져나가고 싶을 때가 생기게 된다.

 

커피 자판기를 생각해 보자. 커피가 자판기 안에 충분하게 있을 때는 항상 "돈을 받으면 커피를 줘라" 라는 조건문을 가진 while문이 수행된다. 자판기가 제 역할을 하려면 커피의 양을 따로이 검사를 해서 커피가 다 떨어지면 while문을 멈추게 하고 "판매중지"란 문구를 자판기에 보여야 할 것이다. 이렇게 while문을 강제로 멈추게 하는 것을 가능하게 해 주는 것이 바로 break이다.

 

다음의 예는 위의 가정을 자바로 표현해 본 것이다.

 

예) 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) 라는 문장이 참이 되므로 if문 다음의 문장들이 수행이 되고 break가 호출되어 while문을 빠져 나가게 된다.

 

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

 

while문 안의 문장을 수행할 때 어떤 조건을 검사해서 조건에 맞지 않는 경우 while문을 빠져나가는 것이 아니라 다시 while문의 맨 처음(조건문)으로 돌아가게 하고 싶을 경우가 생기게 된다. 만약 1부터 10까지의 수중에서 홀수만을 출력하는 것을 while문을 이용해서 작성한다고 생각해 보자. 어떤 방법이 좋을까?

 

예) continue의 사용


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문