반복문이란 while do-while for 향상된 for break · continue 중첩 · 무한루프 📝 문제풀이
◀ 이전 📋 목차 CH 08 ▶
🔁 CHAPTER 07 · 입문

같은 일을 여러 번, 반복문으로 시키기

"1부터 100까지 출력해줘"를 손으로 100줄 복붙할 순 없겠죠? 반복문은 "같은 일을 반복하라"고 컴퓨터에게 딱 한 번만 시키는 문법이에요. 조건문(CH06)을 이해했다면 반복문은 자연스럽게 이어집니다.

🎯 이 장을 끝내면
📖
반복문이란
"복붙 100번" 대신 "반복하라" 한 줄
반복문은 게으름이 아니라, 실수를 없애는 기술이에요.

반복문(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("안녕하세요");
}
🤔 왜 반복문을 배울까? 1. 복붙을 없애요 — 같은 코드를 여러 번 쓰지 않아요. 코드가 짧고 깔끔해져요.
2. 횟수를 자유롭게 — 5번이든 1만 번이든, 숫자 하나만 바꾸면 돼요.
3. 데이터를 훑을 수 있어요 — "성적표의 모든 점수를 더해라" 같은 일은 반복문 없이는 못 해요. (다음 장 배열과 짝을 이뤄요.) 한마디로 반복문은 프로그래밍의 4대 기본기(순차·조건·반복·함수) 중 하나예요. 조건문이 "갈림길"이라면, 반복문은 "제자리 도는 회전목마"라고 보면 돼요.

자바에는 반복문이 네 가지 있어요. 이 장에서 하나씩 볼 거예요.

while do-while for for-each break continue 중첩 반복 무한루프
🧭
공통 부품 하나. 모든 반복문에는 "언제 멈출지"를 정하는 조건이 있어요. 조건이 true인 동안 반복하고, false가 되면 멈춰요. 이게 반복문의 심장입니다.
🔄
while
"조건이 참인 동안" 계속 반복
가장 기본적이고 순수한 반복문이에요.

while은 영어 그대로 "~하는 동안"이에요. 조건이 참(true)인 동안 중괄호 { } 안의 코드를 계속 실행해요. 형태는 이렇게 생겼어요.

while (조건) {
    // 조건이 true인 동안 반복할 코드
}

실제 예제로 "1부터 5까지 출력"을 만들어 볼게요. 반복을 세는 변수 i를 하나 만들고, 매번 1씩 늘려주는 게 핵심이에요.

🔤
카운터 변수(counter) — 반복이 몇 번째인지 세기 위해 두는 변수예요. 흔히 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 = 1
조건 검사
i <= 5 ?
🖨️
본문 실행
출력 + i++
🛑
거짓이면
반복 종료
⚠️
가장 흔한 실수 — i++를 빠뜨리기. 위 코드에서 i++를 지우면 i가 영원히 1이라, 1 <= 5가 계속 참이에요. 프로그램이 멈추지 않는 무한루프에 빠져요. (sec-6에서 다시 봅니다.) 반복문 안에는 조건을 언젠가 거짓으로 만드는 무언가가 반드시 있어야 해요.
🗣️ 언제 while을 쓰나요? 반복 횟수를 미리 모를 때while의 무대예요. 예를 들어 "사용자가 0을 입력할 때까지 계속 받기"처럼, 몇 번 반복할지 실행 전에는 알 수 없는 상황이죠. 반대로 "정확히 5번" 같은 정해진 횟수 반복은 뒤에 나올 for가 더 깔끔해요. 물론 while로도 다 됩니다.
🔂
do-while
"일단 한 번은 하고" 조건을 본다
while과 딱 하나 다른데, 그 차이가 중요해요.

do-whilewhile과 거의 같지만, 조건 검사 순서가 반대예요. 먼저 본문을 한 번 실행하고, 그다음에 조건을 검사해요. 그래서 조건이 처음부터 거짓이어도 최소 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 실행!   (딱 한 번)
🔍 while vs do-while — 핵심 차이 while — 조건 검사 → (참이면) 실행. 0번 실행될 수 있어요. ("검사 먼저")
do-while — 실행 → 조건 검사 → (참이면) 다시 실행. 최소 1번은 실행돼요. ("실행 먼저") 💡 기억법: do(하라)가 앞에 있으니 "일단 하고 나서 물어본다". 그래서 조건이 뭐든 한 번은 해요.
💡
do-while은 언제? "메뉴를 보여주고 → 입력을 받는" 일처럼, 무슨 일이 있어도 처음 한 번은 실행해야 하는 경우에 딱이에요. 예: "일단 메뉴를 띄우고, 사용자가 '종료'를 고를 때까지 반복." 실무에선 while·for보다 덜 쓰이지만, "1회 보장"이라는 성격은 시험에 자주 나와요.
🎯
for
횟수가 정해졌다면, for가 최고
세 부분을 한 줄에 모아 둔, 가장 많이 쓰는 반복문이에요.

forwhile로 하던 "① 변수 준비 → ② 조건 검사 → ③ 값 증가"를 한 줄에 깔끔하게 모아 둔 반복문이에요. 세 부분을 세미콜론 두 개로 나눠 씁니다.

for (초기화 ; 조건 ; 증감) {
    // 반복할 코드
}

"1부터 5까지 출력"을 for로 다시 써 볼게요. 앞서 while로 만든 것과 결과는 똑같지만, 반복에 필요한 정보가 한곳에 모여 있어요.

for (int i = 1 ; i <= 5 ; i++) {
    System.out.println(i);
}
// 출력: 1  2  3  4  5
🧩 for의 세 부분을 분해하면 ① 초기화 int i = 1 — 반복 시작 전 딱 한 번만 실행. 카운터 변수를 준비해요.
② 조건 i <= 5 — 매 회차 시작마다 검사. 참이면 본문 실행, 거짓이면 종료.
③ 증감 i++ — 본문을 한 번 실행한 에 실행. 보통 카운터를 늘리거나 줄여요. for"준비·멈출조건·값바꾸기"를 한 줄에 모아 둔 거예요. while과 하는 일은 똑같아요.

실행 순서가 헷갈리기 쉬우니 한 회차씩 따라가 볼게요. 초기화는 맨 처음 한 번만, 그 뒤로는 조건 → 본문 → 증감 → 조건 → 본문 → 증감…이 반복돼요.

🔤
용어 — 회차(iteration). 반복문이 본문을 한 번 실행하는 것을 "한 회차"라고 불러요. "3회차"는 반복문이 세 번째로 도는 순간이에요. 뒤에 나올 break·continue를 이해할 때 이 말이 자주 쓰이니 지금 눈에 익혀 두세요.
순서실행되는 것i 값결과
1초기화 int i=1 (한 번만)1
2조건 1<=5 → 참 → 본문11 출력
3증감 i++ → 조건 2<=5 참 → 본문22 출력
4증감 → 조건 3<=5 참 → 본문33 출력
계속…4, 54, 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번이고요.
☕ 번외 — 합 구하기: 반복문의 진짜 쓸모
반복문은 출력만 하는 게 아니라 값을 쌓아가는 데 진짜 힘을 발휘해요. "1부터 10까지 더하기"를 볼게요. 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-each — 인덱스 없이 하나씩 꺼내기
배열이나 목록을 처음부터 끝까지 훑을 때 가장 편해요.

배열(여러 값을 담는 상자, 다음 장에서 배워요)의 모든 요소를 하나씩 처리하고 싶을 때가 많아요. 일반 for로도 되지만, 인덱스 번호가 필요 없을 때는 더 간단한 향상된 for(enhanced for), 흔히 for-each라 부르는 문법이 있어요.

🔤
요소(element) — 배열에 담긴 값 하나하나를 가리키는 말이에요. 성적 배열 {90, 85, 100, 70}에는 요소가 4개 들어 있는 거죠. 반복문은 이 요소들을 하나씩 꺼내 처리해요.
🔤
인덱스(index) — 배열에서 몇 번째 자리인지 가리키는 번호예요. 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
🔍 일반 for vs 향상된 for, 언제 뭘 쓸까? 향상된 for — 코드가 짧고 읽기 쉬워요. "그냥 전부 하나씩 볼래" 할 때 최고. 단, 지금 몇 번째인지(인덱스)를 알 수 없고, 값을 꺼내 읽는 용도에 맞아요.
일반 for인덱스가 필요할 때(예: 짝수 번째만, 뒤에서부터), 또는 배열의 값을 바꿔야 할 때는 일반 for가 맞아요. 💡 "번호는 필요 없고 값만 하나씩 보면 돼" → 향상된 for. "몇 번째인지 알아야 해" → 일반 for. 이 기준이면 충분해요.
📦
배열이 아직 낯설어도 괜찮아요. 향상된 for는 다음 장(CH 08 배열)과 짝을 이루는 문법이에요. 지금은 "여러 값을 하나씩 꺼내 반복하는 간편한 for가 있다"는 감만 잡아 두세요. 배열을 배우면 이 문법이 훨씬 자연스러워집니다.
🚦
break · continue
반복을 "멈추거나" "건너뛰거나"
이름은 비슷하지만 하는 일이 완전히 달라요.

반복 도중에 흐름을 바꾸는 두 명령이 있어요. break반복문 전체를 즉시 탈출하고, continue이번 회차만 건너뛰고 다음 회차로 넘어가요.

🚪 break vs continue break — "그만!" 반복문을 완전히 빠져나가요. 뒤의 회차는 아예 실행 안 돼요.
continue — "이번 건 패스!" 지금 회차의 남은 코드만 건너뛰고, 다음 회차를 계속 진행해요. 반복은 멈추지 않아요. 비유: 계단을 오르다가… break계단에서 내려와 버리기, continue한 칸을 건너뛰고 계속 오르기예요.

같은 반복문에 breakcontinue를 각각 넣어 출력 차이를 봐요.

// ── 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 = 이번 것만 건너뛰기(계속). 위 출력에서 break3부터 뒤가 다 사라지고, continue3만 빠진다는 걸 꼭 기억하세요.
🌀
중첩 · 무한루프
반복 속의 반복, 그리고 조심할 함정
구구단으로 중첩을 배우고, 무한루프를 피하는 법을 챙겨요.

중첩 반복문(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를 돌아요.

🔢 중첩 반복의 총 실행 횟수 바깥이 8번(2~9단), 그 안에서 안쪽이 9번(1~9)씩 도니까, 안쪽 본문은 총 8 × 9 = 72번 실행돼요. 중첩은 이렇게 곱셈으로 횟수가 커지므로, 너무 깊게 겹치면(3중·4중) 느려질 수 있어요. 지금은 2중까지만 편하게 다뤄도 충분합니다.

마지막으로 반복문에서 가장 조심할 무한루프(infinite loop)예요. 조건이 영원히 거짓이 안 되는 반복문이라, 프로그램이 멈추지 않고 계속 돌아요. 대표적인 두 원인을 볼게요.

// ① 증감을 빠뜨림 → i가 영원히 1 → 조건 계속 참
int i = 1;
while (i <= 5) {
    System.out.println(i);
    // i++;  ← 이걸 깜빡하면 무한루프!
}

// ② 대놓고 항상 참 → while(true)는 스스로 안 멈춤
while (true) {
    System.out.println("멈추지 않아요...");
    // break나 return이 없으면 영원히 반복
}
⚠️
무한루프를 피하는 3가지 습관. ① 반복문 안에 조건을 언젠가 거짓으로 만드는 코드(예: i++)가 있는지 확인하기. ② while(true)를 쓸 땐 안에 break가 반드시 있게 하기. ③ 부등호 방향(</>)과 증감 방향이 서로 맞는지 보기(예: i를 늘리는데 조건은 i > 0이면 끝나지 않아요).
☕ 번외 — while(true)가 항상 나쁜 걸까?
아니에요! while(true)일부러 쓰는 정상적인 패턴이기도 해요. "언제 끝날지 모르지만, 특정 상황이 되면 그때 멈추고 싶을 때" 유용하죠.
while (true) {
    // ...사용자 입력을 계속 받다가...
    if (입력값이_종료명령) {
        break;          // 이 순간에만 탈출
    }
}
핵심은 "항상 참인 반복문 안에 확실한 탈출구(break)가 있느냐"예요. 탈출구가 있으면 의도된 반복, 없으면 버그(무한루프)입니다.
🧠 이 장 핵심 요약
📝
문제풀이 · 점검
배운 걸 가볍게 점검해봐요
시험이 아니라 "내가 이해했나" 확인용이에요. 틀려도 바로 해설이 나와요.
🧪
문제를 풀면 즉시 정답과 해설이 나오고, 위쪽 바에 점수가 쌓여요. 네 가지 유형(객관식 · O/X · 빈칸 · 코드결과)을 섞어 두었어요. 편하게 눌러보세요.
CH 08 📦 배열 — 여러 값을 한 상자에 담고, 반복문으로 훑어보기