2025-08-24 13:28

개발자 필독서 반복문 핸드북 모든 것을 알려드립니다

컴퓨터 과학의 역사는 ‘자동화’의 역사와 같습니다. 인간의 반복적인 작업을 어떻게 하면 컴퓨터에게 효율적으로 시킬 수 있을까? 이 질문에 대한 가장 우아하고 강력한 해답이 바로 반복문입니다. 초보 개발자에게는 낯선 문법일 수 있지만, 반복문은 프로그램을 살아 움직이게 만드는 심장과도 같은 존재입니다.

이 핸드북은 여러분을 반복문의 세계로 안내하는 완벽한 가이드가 될 것입니다. 자, 이제 컴퓨터처럼 생각하고, 반복의 힘을 마스터하러 떠나볼까요?

1. 반복문의 탄생 배경: 왜 우리는 반복해야만 하는가?

반복문을 배우기 전에, 우리는 ‘왜’ 이 개념이 필요했는지부터 이해해야 합니다.

컴퓨터가 세상에 처음 등장했을 때, 주요 임무 중 하나는 복잡하고 반복적인 계산이었습니다. 예를 들어, 탄도 미사일의 궤적을 계산하거나, 수천 개의 데이터를 정렬하는 작업을 상상해 보세요. 만약 프로그래머가 “1번 데이터 처리”, “2번 데이터 처리”, … “1000번 데이터 처리”와 같이 코드를 1000번 작성해야 했다면 어땠을까요?

이는 단순히 비효율적인 것을 넘어, 실수가 발생할 확률이 기하급수적으로 높아지고 코드의 유지보수가 거의 불가능해지는 재앙과도 같았을 겁니다.

이러한 문제의식 속에서 “Don’t Repeat Yourself (DRY)” 라는 프로그래밍의 핵심 원칙이 탄생했습니다. “같은 일을 반복하지 마라.” 이 원칙을 코드 레벨에서 실현시켜주는 가장 기본적인 도구가 바로 반복문입니다.

반복문은 프로그래머가 ‘어떤 조건이 만족되는 동안’ 혹은 ‘정해진 횟수만큼’ 특정 코드 블록을 계속해서 실행하도록 컴퓨터에 지시하는 구조입니다. 덕분에 우리는 단 몇 줄의 코드로 수천, 수만 번의 작업을 손쉽게 처리할 수 있게 되었습니다.

비유로 이해하기: 반복문은 ‘운동 루틴’과 같습니다. “팔굽혀펴기 10회, 윗몸일으키기 20회, 스쿼트 15회를 1세트로 하여 총 3세트 반복하세요”라는 지시가 있다면, 우리는 각 동작을 3번씩 나열하지 않고 ‘3세트 반복’이라는 간단한 명령으로 전체 운동을 이해합니다. 반복문이 바로 코드 세계의 ‘루틴’인 셈입니다.

2. 반복문의 기본 구조: 무엇으로 이루어져 있는가?

모든 반복문이 똑같이 생기지는 않았지만, 대부분의 반복문은 다음과 같은 4가지 핵심 요소를 공유합니다. 가장 대표적인 for 반복문을 예로 들어 그 구조를 해부해 보겠습니다.

// 0부터 9까지 숫자를 출력하는 for 반복문
for (let i = 0; i < 10; i++) {
  console.log(i); // 실행할 코드
}
  1. 초기화 (Initialization): let i = 0;

    • 반복문이 처음 시작될 때 단 한 번 실행되는 부분입니다.

    • 주로 반복 횟수를 세는 변수(카운터 변수, 여기서는 i)를 선언하고 초기값을 할당합니다. “어디서부터 시작할 것인가?”를 정의합니다.

  2. 조건식 (Condition): i < 10;

    • 반복문의 각 회전(iteration)이 시작되기 전에 매번 검사하는 부분입니다.

    • 이 조건식이 true를 반환하면 반복문 내부의 코드가 실행되고, false를 반환하면 반복문이 즉시 종료됩니다. “언제까지 반복할 것인가?”를 결정합니다.

  3. 증감식 (Increment/Decrement): i++

    • 반복문 내부의 코드가 한 번 실행된 직후에 실행되는 부분입니다.

    • 주로 카운터 변수의 값을 증가시키거나 감소시켜, 언젠가는 조건식이 false가 되어 반복문이 끝날 수 있도록 만듭니다. “다음 단계로 어떻게 나아갈 것인가?”를 명시합니다.

  4. 코드 블록 (Code Block): { console.log(i); }

    • 조건식이 true일 때마다 반복적으로 실행되는 실제 코드입니다.

    • 이 블록 안에는 변수를 조작하거나, 함수를 호출하는 등 원하는 모든 로직을 넣을 수 있습니다.

이 네 가지 요소가 유기적으로 작동하며, 우리는 원하는 만큼 정확하게 코드를 반복 실행할 수 있습니다.

3. 반복문의 종류와 사용법: 상황에 맞는 최적의 도구 선택하기

프로그래밍 언어들은 다양한 상황에 맞춰 사용할 수 있도록 여러 종류의 반복문을 제공합니다. 어떤 망치가 모든 못에 맞지 않듯, 어떤 반복문이 모든 상황에 최적인 것은 아닙니다. 각 반복문의 특징과 사용 사례를 정확히 알아봅시다. (예시는 JavaScript를 기준으로 작성되었습니다.)

1) for 반복문

가장 기본적이고 널리 사용되는 반복문입니다. 반복 횟수가 비교적 명확할 때 주로 사용됩니다.

  • 구조: for (초기화; 조건식; 증감식) { ... }

  • 특징: 초기화, 조건식, 증감식이 한 줄에 명시되어 있어 반복의 전체 흐름을 한눈에 파악하기 쉽습니다.

  • 예시: 배열의 모든 요소를 순서대로 출력하기

    const fruits = ['사과', '바나나', '체리'];
    for (let i = 0; i < fruits.length; i++) {
      console.log(`${i + 1}번째 과일: ${fruits[i]}`);
    }
  • 언제 사용하면 좋을까요?

    • 0부터 100까지 숫자를 더하는 것처럼 정해진 횟수만큼 반복해야 할 때

    • 배열의 인덱스(순서)와 값을 모두 사용해야 할 때

2) while 반복문

특정 조건이 만족되는 동안 계속해서 코드를 반복하고 싶을 때 사용합니다. for문과 달리, 반복 횟수를 미리 알지 못하는 경우에 매우 유용합니다.

  • 구조: while (조건식) { ... }

  • 특징: 조건식만을 괄호 안에 넣습니다. 초기화는 while문 이전에, 증감식은 코드 블록 내부에 직접 작성해야 합니다. 증감식을 빠뜨리면 무한 루프에 빠질 위험이 있습니다.

  • 예시: 사용자가 ‘그만’을 입력할 때까지 계속해서 입력을 받기

    let input = '';
    while (input !== '그만') {
      input = prompt("계속하려면 아무거나 입력하고, 멈추려면 '그만'을 입력하세요.");
      console.log(`입력한 값: ${input}`);
    }
    console.log("프로그램을 종료합니다.");
  • 언제 사용하면 좋을까요?

    • 사용자의 입력, 파일의 끝, 네트워크 응답 등 외부 요인에 의해 반복이 종료될 때

    • 반복 횟수를 예측할 수 없을 때

3) do…while 반복문

while문과 매우 유사하지만, 코드 블록을 최소 한 번은 반드시 실행한다는 중요한 차이점이 있습니다. 조건을 나중에 검사하기 때문입니다.

  • 구조: do { ... } while (조건식);

  • 특징: 먼저 do 블록의 코드를 실행한 후, while의 조건식을 검사하여 반복 여부를 결정합니다.

  • 예시: 사용자에게 메뉴를 최소 한 번은 보여주고 유효한 값을 입력받을 때까지 반복하기

    let selection;
    do {
      selection = prompt("1: 시작, 2: 설정, 3: 종료 중 하나를 선택하세요.");
    } while (selection !== '1' && selection !== '2' && selection !== '3');
    console.log(`선택한 메뉴: ${selection}`);
  • 언제 사용하면 좋을까요?

    • 반복 조건과 상관없이, 로직을 반드시 한 번은 실행해야 하는 경우

4) for…of 반복문 (ES6+)

배열, 문자열, Map, Set 등 반복 가능한(iterable) 객체의 **값(value)**을 순회하기 위해 등장한 현대적인 반복문입니다.

  • 구조: for (const 변수 of 반복가능한객체) { ... }

  • 특징: 코드가 매우 간결하고 직관적입니다. 인덱스를 신경 쓸 필요 없이 각 요소의 값에만 집중할 수 있습니다.

  • 예시: 배열의 각 과일 이름을 출력하기

    const fruits = ['사과', '바나나', '체리'];
    for (const fruit of fruits) {
      console.log(fruit); // '사과', '바나나', '체리'가 차례로 출력됨
    }
  • 언제 사용하면 좋을까요?

    • 배열의 값을 순서대로 하나씩 사용하고 싶을 때 (가장 추천되는 방식)

    • 인덱스가 필요 없을 때

5) for…in 반복문

객체(Object)의 **속성(property) 이름(key)**을 순회하기 위해 사용됩니다. 배열에 사용하는 것은 권장되지 않습니다.

  • 구조: for (const 변수 in 객체) { ... }

  • 특징: 객체의 키 값을 문자열 형태로 가져옵니다. 순서를 보장하지 않으므로 배열 순회가 중요한 작업에는 부적합합니다.

  • 예시: 사용자의 정보를 담은 객체의 키와 값을 모두 출력하기

    const user = {
      name: '홍길동',
      age: 30,
      city: '서울'
    };
    for (const key in user) {
      console.log(`${key}: ${user[key]}`);
    }
    
  • 언제 사용하면 좋을까요?

    • 일반 객체의 모든 속성을 확인하고 싶을 때
반복문 종류주요 사용처특징
for반복 횟수가 명확한 경우, 인덱스 필요 시가장 범용적, 구조가 명확함
while반복 횟수가 불명확하고 조건이 중요할 때조건에 따라 0번 실행될 수도 있음
do...while코드를 최소 1번은 실행해야 할 때선실행 후조건 검사
for...of배열 등 반복 가능한 객체의 ‘값’ 순회 시간결하고 직관적, 인덱스 불필요 시 최적
for...in일반 객체의 ‘속성(키)’ 순회 시순서를 보장하지 않음, 배열 사용 비권장

4. 심화 내용: 반복문을 제어하는 기술

숙련된 개발자는 단순히 반복문을 사용하는 것을 넘어, 필요에 따라 그 흐름을 자유자재로 제어합니다.

1) break와 continue

  • break: “탈출!”

    • break 문을 만나면, 가장 가까운 반복문이 즉시 완전히 종료됩니다. 조건식의 결과와 상관없이 강제로 반복을 멈춥니다.

    • 예시: 배열에서 특정 값을 찾으면 더 이상 검색하지 않고 멈추기

      const numbers = [1, 5, 10, 15, 20];
      for (const num of numbers) {
        if (num === 10) {
          console.log("10을 찾았습니다!");
          break; // 반복문 즉시 종료
        }
        console.log(num); // 1, 5 출력 후 10을 만나 종료됨
      }
      
  • continue: “이번만 건너뛰기!”

    • continue 문을 만나면, 현재 진행 중인 반복 회차의 나머지 코드를 건너뛰고 즉시 다음 회차로 넘어갑니다. 반복문 자체를 종료하지는 않습니다.

    • 예시: 배열에서 홀수만 출력하기 (짝수는 건너뛰기)

      for (let i = 1; i <= 10; i++) {
        if (i % 2 === 0) { // 짝수이면
          continue; // 아래 console.log를 실행하지 않고 다음 i로 넘어감
        }
        console.log(i); // 1, 3, 5, 7, 9 출력
      }
      

2) 중첩 반복문 (Nested Loops)

반복문 안에 또 다른 반복문이 들어가는 구조입니다. 2차원 배열을 다루거나, 구구단, 별 찍기 패턴 등을 만들 때 유용하게 사용됩니다.

  • 예시: 구구단 2단부터 9단까지 출력하기

    for (let i = 2; i <= 9; i++) { // 바깥쪽 반복문 (단)
      console.log(`--- ${i}단 ---`);
      for (let j = 1; j <= 9; j++) { // 안쪽 반복문 (곱하는 수)
        console.log(`${i} x ${j} = ${i * j}`);
      }
    }
    
  • 주의점: 중첩이 깊어질수록 실행 횟수가 기하급수적으로 늘어나(O(n²), O(n³)…) 성능에 심각한 영향을 줄 수 있습니다. 3중첩 이상의 반복문은 가급적 피하고 다른 알고리즘을 고민하는 것이 좋습니다.

3) 무한 루프 (Infinite Loop)

반복문의 조건식이 항상 true가 되어 영원히 끝나지 않는 상태를 말합니다. 대부분의 경우 프로그래머의 실수로 발생하며, 프로그램을 멈추게 하는 원인이 됩니다.

  • 실수 예시:

    let i = 0;
    while (i < 10) {
      console.log("이 루프는 끝나지 않아요!");
      // i를 증가시키는 증감식이 없음!
    }
    
  • 의도적인 사용: 게임 루프, 서버의 요청 대기, 임베디드 시스템 등 프로그램이 종료되지 않고 계속 실행되어야 하는 특정 상황에서는 의도적으로 무한 루프(while (true) { ... })를 사용하고 내부에서 break 조건으로 탈출하기도 합니다.

결론: 반복은 지루한 것이 아니라 강력한 것이다

오늘 우리는 반복문이라는 도구가 왜 필요하게 되었는지부터 시작하여, 그 구조와 다양한 종류, 그리고 흐름을 제어하는 고급 기술까지 살펴보았습니다.

반복문은 단순히 코드를 줄여주는 편의 기능이 아닙니다. 그것은 복잡한 문제를 작고 반복 가능한 단위로 분해하여 해결하는, **컴퓨터적 사고(Computational Thinking)**의 핵심입니다. 어떤 반복문을 선택하느냐에 따라 코드의 가독성과 효율성이 크게 달라질 수 있습니다.

이제 여러분의 손에는 다양한 종류의 망치가 쥐어져 있습니다. 어떤 못을 박아야 할지 고민하고, 가장 적절한 망치를 선택하여 힘껏 내리치세요. 수많은 반복을 통해 여러분의 코드는 더욱 견고하고 우아해질 것입니다.

이제 직접 코드를 작성하며 다양한 반복문을 실험해 보세요. 그것이 반복문을 완벽하게 마스터하는 유일한 길입니다.

레퍼런스(References)

반복문