"1부터 100까지 출력해줘"를 손으로 100줄 복붙할 순 없겠죠? 반복문은 "같은 일을 반복하라"고 컴퓨터에게 딱 한 번만 시키는 문법이에요. 조건문(CH06)을 이해했다면 반복문은 자연스럽게 이어집니다.
while, do-while, for 세 가지 반복문을 골라 쓸 수 있어요.for의 초기화·조건·증감 세 부분과 실행 순서를 그릴 수 있어요.break와 continue의 차이를 코드로 구분해요.반복문(loop)은 "같은(혹은 비슷한) 일을 여러 번 실행하라"고 지시하는 문법이에요. 예를 들어 "안녕하세요"를 다섯 번 출력하고 싶다고 해봐요. 반복문이 없다면 이렇게 써야 해요.
System.out.println("안녕하세요");
System.out.println("안녕하세요");
System.out.println("안녕하세요");
System.out.println("안녕하세요");
System.out.println("안녕하세요");
다섯 번이면 참을 만하죠. 그런데 1000번이라면요? 손으로 1000줄을 복붙하는 건 불가능에 가깝고, 중간에 하나만 오타 나도 찾기 힘들어요. 반복문을 쓰면 딱 몇 줄로 끝나요.
for (int i = 0; i < 5; i++) {
System.out.println("안녕하세요");
}
자바에는 반복문이 네 가지 있어요. 이 장에서 하나씩 볼 거예요.
true인 동안 반복하고, false가 되면 멈춰요. 이게 반복문의 심장입니다.while은 영어 그대로 "~하는 동안"이에요. 조건이 참(true)인 동안 중괄호 { } 안의 코드를 계속 실행해요. 형태는 이렇게 생겼어요.
while (조건) {
// 조건이 true인 동안 반복할 코드
}
실제 예제로 "1부터 5까지 출력"을 만들어 볼게요. 반복을 세는 변수 i를 하나 만들고, 매번 1씩 늘려주는 게 핵심이에요.
i라는 이름을 쓰는데(index의 i에서 왔어요), 보통 0이나 1부터 시작해 매 회차 1씩 늘려가며 "지금 몇 번째인지"를 기억해요. 이 값이 조건을 언젠가 거짓으로 만들어 반복을 멈추게 하죠.int i = 1; // ① 시작값 준비
while (i <= 5) { // ② i가 5 이하인 동안 반복
System.out.println(i); // ③ 현재 값 출력
i++; // ④ i를 1 증가 (아주 중요!)
}
// 출력: 1 2 3 4 5
흐름을 따라가 볼게요. 처음 i는 1이에요. 1 <= 5는 참이니 1을 출력하고 i를 2로 만들어요. 다시 조건을 확인하고… 이걸 반복하다가 i가 6이 되면 6 <= 5가 거짓이 되어 멈춰요.
i++를 빠뜨리기. 위 코드에서 i++를 지우면 i가 영원히 1이라, 1 <= 5가 계속 참이에요. 프로그램이 멈추지 않는 무한루프에 빠져요. (sec-6에서 다시 봅니다.) 반복문 안에는 조건을 언젠가 거짓으로 만드는 무언가가 반드시 있어야 해요.while의 무대예요. 예를 들어 "사용자가 0을 입력할 때까지 계속 받기"처럼, 몇 번 반복할지 실행 전에는 알 수 없는 상황이죠.
반대로 "정확히 5번" 같은 정해진 횟수 반복은 뒤에 나올 for가 더 깔끔해요. 물론 while로도 다 됩니다.
do-while은 while과 거의 같지만, 조건 검사 순서가 반대예요. 먼저 본문을 한 번 실행하고, 그다음에 조건을 검사해요. 그래서 조건이 처음부터 거짓이어도 최소 1회는 무조건 실행돼요.
do {
// 이 코드는 최소 한 번은 반드시 실행됨
} while (조건); // ← 세미콜론(;) 꼭 붙여요!
차이를 눈으로 확인하려고, 조건이 처음부터 거짓인 상황을 만들어 볼게요.
// ── while: 조건이 처음부터 거짓 → 본문 0번 실행 ──
int a = 10;
while (a < 5) {
System.out.println("while 실행!");
}
// (아무것도 출력 안 됨)
// ── do-while: 조건이 처음부터 거짓 → 그래도 1번 실행 ──
int b = 10;
do {
System.out.println("do-while 실행!");
} while (b < 5);
// 출력: do-while 실행! (딱 한 번)
do(하라)가 앞에 있으니 "일단 하고 나서 물어본다". 그래서 조건이 뭐든 한 번은 해요.
while·for보다 덜 쓰이지만, "1회 보장"이라는 성격은 시험에 자주 나와요.for는 while로 하던 "① 변수 준비 → ② 조건 검사 → ③ 값 증가"를 한 줄에 깔끔하게 모아 둔 반복문이에요. 세 부분을 세미콜론 두 개로 나눠 씁니다.
for (초기화 ; 조건 ; 증감) {
// 반복할 코드
}
"1부터 5까지 출력"을 for로 다시 써 볼게요. 앞서 while로 만든 것과 결과는 똑같지만, 반복에 필요한 정보가 한곳에 모여 있어요.
for (int i = 1 ; i <= 5 ; i++) {
System.out.println(i);
}
// 출력: 1 2 3 4 5
int i = 1 — 반복 시작 전 딱 한 번만 실행. 카운터 변수를 준비해요.i <= 5 — 매 회차 시작마다 검사. 참이면 본문 실행, 거짓이면 종료.i++ — 본문을 한 번 실행한 뒤에 실행. 보통 카운터를 늘리거나 줄여요.
즉 for는 "준비·멈출조건·값바꾸기"를 한 줄에 모아 둔 거예요. while과 하는 일은 똑같아요.
실행 순서가 헷갈리기 쉬우니 한 회차씩 따라가 볼게요. 초기화는 맨 처음 한 번만, 그 뒤로는 조건 → 본문 → 증감 → 조건 → 본문 → 증감…이 반복돼요.
break·continue를 이해할 때 이 말이 자주 쓰이니 지금 눈에 익혀 두세요.| 순서 | 실행되는 것 | i 값 | 결과 |
|---|---|---|---|
| 1 | 초기화 int i=1 (한 번만) | 1 | — |
| 2 | 조건 1<=5 → 참 → 본문 | 1 | 1 출력 |
| 3 | 증감 i++ → 조건 2<=5 참 → 본문 | 2 | 2 출력 |
| 4 | 증감 → 조건 3<=5 참 → 본문 | 3 | 3 출력 |
| … | 계속… | 4, 5 | 4, 5 출력 |
| 끝 | 증감 → 조건 6<=5 거짓 → 종료 | 6 | 반복 끝 |
for (int i = 0; i < 5; i++) 처럼 0부터 시작해 i < 5면, i는 0·1·2·3·4 → 정확히 5번 돌아요. 실무에서 이 "0부터 <N" 패턴을 가장 많이 써요(배열과 잘 맞아서 — 다음 장!). 1부터 i <= 5도 5번이고요.sum이라는 누적 변수를 0으로 두고, 반복할 때마다 더해 나가요.
int sum = 0;
for (int i = 1; i <= 10; i++) {
sum = sum + i; // sum += i; 와 같음
}
System.out.println(sum); // 55
1+2+3+…+10 = 55. 만약 10을 100으로만 바꾸면 1~100의 합이 나와요. 이 "누적 변수 + 반복문" 패턴은 평균·최댓값·개수 세기 등 어디에나 등장하니 꼭 익혀 두세요.
배열(여러 값을 담는 상자, 다음 장에서 배워요)의 모든 요소를 하나씩 처리하고 싶을 때가 많아요. 일반 for로도 되지만, 인덱스 번호가 필요 없을 때는 더 간단한 향상된 for(enhanced for), 흔히 for-each라 부르는 문법이 있어요.
{90, 85, 100, 70}에는 요소가 4개 들어 있는 거죠. 반복문은 이 요소들을 하나씩 꺼내 처리해요.scores[0]의 0이 인덱스죠. 자바는 0부터 세서 첫 번째가 0번이에요. 향상된 for는 이 번호를 신경 쓰지 않고 값만 꺼내 줘서 편해요. (배열과 인덱스는 다음 장에서 자세히 배우니, 여기선 "자리 번호"라는 감만 잡아 두세요.)for (타입 변수 : 배열이나컬렉션) {
// 요소를 하나씩 '변수'에 담아 반복
}
기호 :는 "~안의 각각을(each of)" 정도로 읽으면 돼요. 성적 배열을 훑어 출력해 볼게요.
int[] scores = {90, 85, 100, 70};
// ── 일반 for (인덱스 사용) ──
for (int i = 0; i < scores.length; i++) {
System.out.println(scores[i]);
}
// ── 향상된 for (인덱스 없이) ──
for (int s : scores) {
System.out.println(s); // s에 90, 85, 100, 70이 차례로 들어옴
}
// 두 반복문의 출력은 똑같음: 90 85 100 70
반복 도중에 흐름을 바꾸는 두 명령이 있어요. break는 반복문 전체를 즉시 탈출하고, continue는 이번 회차만 건너뛰고 다음 회차로 넘어가요.
break는 계단에서 내려와 버리기, continue는 한 칸을 건너뛰고 계속 오르기예요.
같은 반복문에 break와 continue를 각각 넣어 출력 차이를 봐요.
// ── break: i가 3이면 반복 자체를 종료 ──
for (int i = 1; i <= 5; i++) {
if (i == 3) {
break; // 여기서 반복문 탈출
}
System.out.println(i);
}
// 출력: 1 2 (3에서 멈춰, 4·5는 아예 안 나옴)
// ── continue: i가 3이면 이번 회차만 건너뜀 ──
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue; // 아래 출력을 건너뛰고 i++로
}
System.out.println(i);
}
// 출력: 1 2 4 5 (3만 빠지고 반복은 끝까지 계속)
break = 반복 끝(탈출), continue = 이번 것만 건너뛰기(계속). 위 출력에서 break는 3부터 뒤가 다 사라지고, continue는 3만 빠진다는 걸 꼭 기억하세요.중첩 반복문(nested loop)은 반복문 안에 또 반복문이 들어간 구조예요. 표·격자·구구단처럼 가로·세로 두 방향으로 반복할 때 써요. 대표 예제인 구구단을 볼게요.
// 구구단 2단 ~ 9단
for (int dan = 2; dan <= 9; dan++) { // 바깥: 단(2~9)
for (int i = 1; i <= 9; i++) { // 안쪽: 곱하는 수(1~9)
System.out.println(dan + " x " + i + " = " + (dan * i));
}
System.out.println("-----"); // 한 단 끝날 때마다 구분선
}
동작을 그려 보면, 바깥 반복이 한 번 돌 때마다 안쪽 반복이 처음부터 끝까지 다 돌아요. 바깥이 dan=2일 때 안쪽 i가 1~9까지 돌며 "2 x 1"부터 "2 x 9"까지 출력하고, 그다음 바깥이 dan=3으로 넘어가 또 1~9를 돌아요.
마지막으로 반복문에서 가장 조심할 무한루프(infinite loop)예요. 조건이 영원히 거짓이 안 되는 반복문이라, 프로그램이 멈추지 않고 계속 돌아요. 대표적인 두 원인을 볼게요.
// ① 증감을 빠뜨림 → i가 영원히 1 → 조건 계속 참
int i = 1;
while (i <= 5) {
System.out.println(i);
// i++; ← 이걸 깜빡하면 무한루프!
}
// ② 대놓고 항상 참 → while(true)는 스스로 안 멈춤
while (true) {
System.out.println("멈추지 않아요...");
// break나 return이 없으면 영원히 반복
}
i++)가 있는지 확인하기. ② while(true)를 쓸 땐 안에 break가 반드시 있게 하기. ③ 부등호 방향(</>)과 증감 방향이 서로 맞는지 보기(예: i를 늘리는데 조건은 i > 0이면 끝나지 않아요).while(true)는 일부러 쓰는 정상적인 패턴이기도 해요. "언제 끝날지 모르지만, 특정 상황이 되면 그때 멈추고 싶을 때" 유용하죠.
while (true) {
// ...사용자 입력을 계속 받다가...
if (입력값이_종료명령) {
break; // 이 순간에만 탈출
}
}
핵심은 "항상 참인 반복문 안에 확실한 탈출구(break)가 있느냐"예요. 탈출구가 있으면 의도된 반복, 없으면 버그(무한루프)입니다.
for(int x : arr). 인덱스 필요 없이 요소를 하나씩 순회.while(true)+탈출구 없음이 주범.