학습 목표
- 반복문 개념 이해하기
- 반복문(while 문, for 문, do 문) 차이 이해하기
- 계수기 이용 반복문과 감시값 이용 반복문 차이 이해하기
- 적절한 반복문 사용하기
반복문이란?
- loop(반복문): 주어진 조건이 만족되는 한 반복적으로 실행
- loop body(반복문 몸체): 반복문 내에서 반복하여 실행되는 문
- Bool 연산식(혹은 조건식): 반복 여부를 결정하기 위해 사용
Java는 다음 3가지 반복문을 제공함
- while 문
- do 문
- for 문
while 문
while 문의 구문법과 의미
- 구문법:
while (조건식)
문; - 의미:
조건식이 참(true)이면 문을 실행하고 다시 조건식을 계산하여 여전히 참이면 문을 실행. 이와 같이 조건식의 결과 값이 거짓(false)이 될 때까지 문을 반복적으로 실행한다. 조건식의 결과 값이 거짓이면 loop를 벗어나고 이후 문을 실행함
10까지 센 후에 발사를 하는 프로그램의 흐름도를 살펴보면 다음과 같다.
다음은 이를 Java 프로그램으로 작성한 것이다.
count 변수의 초기 값은 10이다. 따라서 처음에 while 문의 조건식 결과는 count의 값이 0 이상이므로 true이다. 따라서 반복문 몸체 내의 문들이 순서대로 실행된다. 그 결과 10이 출력되고 count 변수 값은 1 만큼 감소되어 9가 된다. 이 경우에도 조건식 결과는 true이다. 따라서 9가 출력되고 count 변수 값은 8이 된다. 이 과정은 count 변수 값이 0이 될 때까지 반복되므로, 0값을 출력 후 최종적으로 count 값이 -1이 되면서 조건식 결과가 false가 되어 반복문을 종료하는 프로그램이다.
우리들이 어떤 과정들을 반복할 때 자연스럽게 다음과 같은 반복 패턴을 따른다.
- 한값을얻는다.
- 그값을처리한다.
- 주어진 조건이 만족된다면 l번으로 긴-다. 아니면 다음으로 간다.
반면에 while 문은 우리에게 다소 부자연스러운 다음과 같은 반복 패턴을 나타낸다.
- 반복문에 들어가기 전에 반복문 제어의 첫 번째 값을 얻는다.
2 조건식의 계산 결과가 true인 동안 다음을 수행힌-다. - 현재 값을처랴한다.
- 반복문 제어의 다음 값을 얻는다.
〈첫 번째 값을 얻는다〉
씨 hile (조건식)
{
〈현재 값을 처리한다〉
〈다음 값을 얻는다〉
}
예를 들면 대학의 한 교수가 시험 채점을 마치고 답안지들 중 첫 번째 100점짜리 답안지를 찾는다고 한다.
do 문
- while문과 달리 먼저 반복문 몸체 내의 문을 실행하고 조건식을 계산함. 따라서 몸체의 문이 적어도 한번을 실행됨
- do 문은 while 문과 같이 조건식의 계산 결과 값이 거짓이 될 때까지 반복문 몸체 내의 문을 실행함
do 문의 구문법과 의미
- 구문법:
do
문:
while (조건식); - 의미:
- 문을 실행한다.
- 조건식을 계산하여 결과가 참인 동안 문을 반복적으로 실행한다.
조건식의 계산 결과가 거짓이면 do 문의 다음 문을 실행한다.
do 문은 반복 제어변수의 값이 do 문 내에서 주어져야 할 때 사용한다.
다음 문제는 1부터 10까지의 정수를 한 줄에 하나씩 출력한다.
다음은 구매한 상품 가격들의 합이 100,000을 초과할 때가지 상품 가격들을 계속 읽어들이는 프로그램이다.
- 가격들의 합은 0이다.
- 가격 하나를 읽어 들인다.
- 읽어 들인 가격을 기격들의 합에 더한다.
- 가격들의 합이 100.000보다 작거나 같으면 2번으로 간다. 아니면 종료한다.
위 알고리즘에서 2번과 3번 과정이 종료 조건(가격들의 합이 100,000보다 크다)이 만족되지 않는 한 반복적으로 실행된다. 따라서 위 알고리즘의 2변 3번과 4번 과정은 do 문을 사용하여 구현할 수 있다. 가격들의 합과 읽어들인 가격을 저장하는 변수는 각각 total과 price이다.
위 알고리즘을 구현한 코드는 다음과 같다,
for 문
실행되기 전에 반복문 몸체를 몇 번 실행 할지를 정확히 아는 경우에 적절한 반복문임
for문의 구문법과 의미
- 구문법:
for (초기 연산식; 종료 조건식; 증가 연산식)
문; - 의미:
- 문을 실행하기 전에 초기 연산식을 한 번 계산한다.
- 종료 조건식을 계산한다. 결과 값이 참이면 문을 실행하고 거짓이면 for문을 종료한다.
- 문을 실행한 후 증가 연산식을 계산한다.
- 2번으로 돌아간다.
for문의 흐름도는 다음과 같다.
다음은 숫자의 합을 구하는 프로그램의 흐름도이다.
다음은 이를 자바로 구현한 코드이다.
중첩 반복문
중첩 반복문(nested loop)은 반복문 톰체 안에 또 다른 반복문을 포함한다. 이 경우 밖의 반복문이 매 변 실행될 때마다 안의 반복문이 전부 실행된다.
다음은 구구단의 각 단을 한 줄에 출력하는 프로그램이다.
break 문과 continue 문
break
break 문은 어떤 반복문의 몸체 안에 있을 수 있다. 반복문 내 의 break 문의 역할은 switch 문 내에서의 역할과 비슷하다. 반복문 몸체에 break 문이 나오면 반복문의 실행이 즉시 중단되고 반복문 다음에 나오는 문이 실행된다.
continue
continue 문은 break 문과 비슷하게 반복문의 실행을 즉시 중단시킨다. 그러나 반복문의 처음으로 돌아가서 반복문의 조건석을 다시 계 산하게 한다. 조건식이 여전히 잠이라면 반복문 몸체가 다시 실행된다.
Warning
break/ continue 문은 for 문이나 do 문 내에도 나올 수 있다. 반복문 내에서 break 문이나 continue 문을 사용하는 것은 꼭 필요히지 않다. 같은 일을 하는 반복문을 break 문이나 continue 문을 사용하지 않고 작성할 수 있다. break/continue 문은 프로그램 의 실행이 한 곳에서 다른 곳으로 옮겨가게 만들기 때문에 표드를 이해하기 어렵게 만든다. 그 결과 오류가 일어냐게 할 수 있다. 따라서 반복문 내에 break/continue 문을 사용하는 것을 가능한 피해야한다.
반복문 제어
- 1) 계수기 제어 반복문(count-controlled loop): 조건식의 일부로서 반복 제어 변수를 사용한다. 우리는 계수기 제어 반복문에 들어가기 전에 반복 제어 변수의 값을 초기화한다. 반복문 내에서 제어 변수의 값을 변경한다. 반복문의 계속 수행 여부는 제어 변수의 값이 특정 값과 비교하여 결정된다. 따라서 계수기 제어 반복문은 보통 일정 횟수만큼 반복된다.
- 2) 감시값 제어 반복문(sentinel-controlled loop): 감시값이라고 부르는 특정 값들의 하나가 나올 때까지 반복문 몸체가 반복적으로 실행된다.
위 코드에서 while 문은 감시값에 의해 반복 여부가 결정되는 감시값 제어 반복문이다.
무한 반복문 (infinite loop)
무한 반복문(infinite loop)은 종료되지 않고 무한히 반복되는 반복문이다. 무한 반복문을 종료하기 위해서는 사용자가 강제로 프로그램을 종료시켜야 한다. 이는 가장 보편적인 논 리 오류이다. 프로그래머는 항상 반복문이 정상적으로 종료되는지를 확인할 펼요가 있다. 다음 예는 무한 반복문이 일어나는 경우이다.
위 코드에서 반복문 몸체에서 변수 product의 값은 5배가 된다. 따라서 product 값은 궁 극적으로 100보다 크게 되어야 한다. 그러나 변수 product의 값이 0으로 초기화 되기 때 문에 product 값은 항상 0이 된다. 그러므로 while 문은 무한히 반복된다.
무한 반복문의 다른 예를 보자.
위 코드에서 변수 count의 값은 0으로 초기화되고 do 문 내에서 1만큼 증가한다. 따라서 count 값은 항상 O보다 크게 된다. 따라서 do 문은 계속 실행된다. 이론적으로 위의 do 문은 무한반복문이다. 그러나 count값이 int형 변수가 저장할 수 있는 최대값보다 커지면 오버플로우(overflow) 오류가 발생한다. 대부분의 프로그래밍 언어들에서는 오버플로우가 발생하면 프로그램이 종료된다. 그러나 자바에서는 프로그램이 종료되지 않고 무한 값을 나타내는 값이 정수형 변수에 저장된다. 무한값보다 큰 값을 정수형 변수에 저장하려고 하면 변수에 최소 음수값이 저장된다. 따라서 count 값이 궁극적으로 음수가 된다. 그러므로 do 문은 끝나게 된다. 반복문에서 반복 여부를 결정하는 조건식에 실수를 사용하는 것은 피해야 한다.
예를 들면 다음 코드를 고려하라.
위 코드에서 do 문은 간단하고 명확해 보인다.
으로 그 값에 0.1을 더하므로 10번 반복한 후에는 count 값은 1.0이 될 것이기 때문에 do 문은 종료되어야 한다. 그러나 실제로 count 값은 결코 1.0이 되지 않는다. 왜냐하면 실수 값은 정확한 값이 아닌 근사값으로 표현되기 때문이다. 위의 do 문이 11번 실행된 결과는 디음과같다.
0.1
0.2
0.30000000000000004
0.4
0.5
0.6
0.7
0.7999999999999999
0.8999999999999999
0.9999999999999999
1.0999999999999999
실제로 위 코드는 종료된다. 자바에서 실수형 변수 값은 나타낼 수 있는 최대 값을 초과하면 오버블로우가 발생하여 비정상적으로 끝나게 된다.
반복문을 작성할 때 주의해야 할 또 다른 점은 1 만큼 차이 오류이다. 우리가 반복문 몸체 를 10번 실행하고 싶다고 가정하자
다음 코드는 정확히 작동되는가?
위 코드는 10번이 아닌 9번 실행된다. 다음 코드를 고려하라.
위 코드는 10번이 아닌 11번 실행된다. 올바른 코드는 다음과 같다.
혹은
반복문 설계 방법
반복문이 포함된 프로그램 내에서 반복문이 어떻게 작동하는지를 이해하는 것은 상대적으로 쉽다. 반면에 주어진 문제를 해결하는 반복문을 설계하는 것은 쉽지 않다. 이 절에서 우리는 반복문을 설계하는 방법을 고려한다. 반복문 설계 과정은 제어 흐름 설계와 반복문 내에서 일어 나는 작업 처리 설계로 나눌 수 있다. 각 작업은 다음과 같이 세 부분으로 이루어진다.
• 작업 그자체
• 초기화
• 갱신
또한 반복문이 종료될 때 프로그램의 상태를 명확하게 기술하는 것도 중요하다. 왜냐하면 반복문은 변수들 값을 임의로 변경할 수 있기 때문이다. 다음은 반복문을 설계할 때 고려해야 할 사항들이다.
- 어떤 조건이 반복문을 끝내는가?
- 반복문의 조건이 어떻게 초기화되어야 하는가?
- 반복문의 조건은 어떻게 갱신되어야 하는가?
- 반복되는 프로세스는 무엇인가?
- 반복되는 프로세스는 어떻게 초기화되는가?
- 반복되는 프로세스는 어떻게 갱신되어야 하는가?
- 반복문이 종료될 때 프로그램의 상태는 무엇인가?
위 고려사항들 중 처음 세 항목은 반복문의 실행을 제어하는 부분을 설계하는 것을 도와준다. 다음 세 항목은 반복문 내의 처리부분을 설계하는 것을 도와준다. 마지막 항목은 반복문이 적절하게 종료된다는 것을 확인해준다.
반복문제어흐름설계
반복문 설계에서 가장 중요한 단계는 반복문이 끝나는 조건을 정하는 것이다. 종료 조건을 잘 정하지 않으면 무한반복문이나 다른 오류들이 발생할 수 있다. 종료조건은 주어진 문제를 자세히 분석힘으로써 찾아낼 수 있다. 예를 들면 문제 내에 ‘100개의 시험 점수들을 더하라’라는 문장이 있다면 종료조건은 계수기가 100이 되는 것이다. 다른 예로 문제 내에 ‘모든 시험 점수들을 더하라’라는 문장이 있다면 종료 조건은 더 이상 시험 점수가 없는 것이다. 또 다른 예로 문제 내에 ‘100점 짜리 시험점수가 입력될 때까지 처리하라'는 문장이 있다면 종료 조건은 100점짜리 시험 점수가 입력되는 것이다.
다음으로 우리는 반복문이 올바르게 시작하는 것을 보장하는 문들과 반복문이 종료 조건에 도달하게 하는 문들을 필요로 한다. 이러한 문들은 종료 조건의 유형에 의존한다. 계수기 제어 반복문에 대해서는 반복문 제어 변수에 초기 값을 줌으로써 종료조건을 초기화한 다. 보통초기 값은 1이다. 다음으로 반복이 이루어질 때마다 제어 변수의 값을 1만큼 증가시켜 종료 조건을 갱신한다. 다음은 100번 반복이 되는 반복문의 경우에 제어 변수의 초기화와 제어 변수 값의 갱신이 이루어지는 예이다.
반복문이 특정 사건의 계수기에 의해 제어된다면 제어 변수는 0으로 초기화되고 특정 사건이 일어날 때마다 l만큼 증가한다. 다음은 100점짜리 시험점수들의 수가 10이 될때까지 반복되는 반복문의 예이다.
반복문내의 작업 처리 설계
반복문 내에 반복되는 처리 과정을 설계할 때는 먼저 매번 반복할 때마다 처리해야 할 일이 무엇인지 결정해야 한다. 우선 반복이 단지 한 번 이루어진다고 가정하라. 이때 어떤 일들을 수행해야 하는가? 이에 대한 답은 문제에 주어져 있다. 예를 들면 한 교과목의 매 수업 시간에 출석하는 학생들의 수를 읽어 들인 후에 평균 출석 학생수를 계산한다고 하자. 이 경우에 매 반복마다 해야 할 일은 매 수업 시간에 출석하는 학생들의 수를 읽어 들이고 이 수를 합계에 더 해야 한다. 매 반복마다 수행되는 일들을 찾아 낸 후에 이를 일반화시켜 반복문 몸체의 설계를 할 수 있다.
반복문나가기설계
종료 조건이 일어나고 프로그램 제어의 흐름이 반복문 다음 문으로 옮겨갈 때 반복문 내에 서 사용된 값들은 그대로 남아 있다. 이러한 값들이 나중에 사용된다면 반복문은 그 값들 을 적절한 상태에 있게 해야 한다. 이러한 이유로 반복문 설계의 마지막 단계는 반복문을 나갈 때 프로그램의 상태를 알아야 한다. 이를 위해 그것의 유효성을 이중으로 확인해야 한다.
올바른 반복문 설계는 많은 경험을 필요로 한다. 예를 들면 다음 코드는 시험 점수들의 수를 센 후 출력한다.
위 코드에서 읽어 들인 점수 score가 -99라면 더 이상 읽어들일 점수가 없다는 것을의 미한다. 위 코드를 실행해 보면 scoreCount의 값이 실제 값보다 1 만큼 크다는 것을 확인 할수있다. 따라서 위 코드는 논리오류가 있음을 알게 되고 scoreCount 변수의 초기값이 1이 이나라 0이 되어야 한다는 것을 찾아내게 된다.
예제 프로그램 작성
점수들을 읽어들여 각 A ~ F 학점들의 수를 구하는 프로그램을 작성해 보자.
-
첫 번째 점수를 읽어 들여 변수 score에 저장한다.
-
score가 양수인 동안 다음을 반복한다.
2.1 totalCount = totalCount + 1
2.2 score >= 90 이라면 Acount = Acount + 1
2.3 80 <= score < 90 이라변 Bcount = Bcount + 1
2.4 70 <= score < 80 이라면 Ccount = Ccount + 1
2.5 60 <= score < 70 이라면 Dcount = Dcount + 1
2.6 score < 60 이라면 Fcount = Fcount + 1 -
점수들의 총수, A ~ F 학점 수를 출력한다.
while 문의 조건식은 score >= 0으로 하면 된다. while 문의 종료를 위한 감시값은 1을 사용한다. 점수에 해당하는 학점 수를 l만큼 증가시카는 부분은 중첩된 if-else 문을 사용하면 된다.
토론이 없습니다