iBetter Books
수정

반복의 힘 — 반복문

"1부터 100까지 출력하세요." 이 문제를 조건문만으로 풀려면 print를 100번 써야 합니다. 하지만 반복문을 쓰면 세 줄이면 됩니다. 컴퓨터가 가진 가장 강력한 능력 중 하나는 바로 이 반복입니다. 지치지 않고, 실수 없이, 수백만 번을 해냅니다.

Dart는 여러 종류의 반복문을 제공합니다. 상황에 맞게 골라 쓰면 코드가 훨씬 읽기 좋아집니다.

for 문 — 횟수가 정해진 반복

반복 횟수를 미리 알고 있을 때 사용합니다. C 언어부터 이어져 온 고전적인 형태입니다.

void main() {
  for (int i = 1; i <= 5; i++) {
    print('반복 $i번째');
  }
}

for 문은 세 부분으로 구성됩니다.

  • int i = 1 — 초기식. 반복을 시작하기 전에 한 번 실행됩니다.
  • i <= 5 — 조건식. 반복을 계속할지 판단합니다. 거짓이 되면 반복을 멈춥니다.
  • i++ — 증감식. 각 반복이 끝난 뒤 실행됩니다.

실행 결과입니다.

반복 1번째
반복 2번째
반복 3번째
반복 4번째
반복 5번째

숫자를 거꾸로 반복하고 싶다면 증감식을 i--로 바꾸면 됩니다.

void main() {
  for (int i = 5; i >= 1; i--) {
    print('카운트다운: $i');
  }
  print('발사!');
}

for-in 문 — 컬렉션 순회

리스트나 세트 같은 컬렉션의 요소를 하나씩 꺼내볼 때는 for-in이 더 간결합니다.

void main() {
  List<String> fruits = ['사과', '바나나', '체리'];

  for (String fruit in fruits) {
    print('과일: $fruit');
  }
}

인덱스 없이 "각 요소를 fruit라는 이름으로 꺼내 쓴다"는 의미가 코드에 그대로 드러납니다. 읽기가 훨씬 자연스럽습니다.

컬렉션은 PART 04에서 자세히 다루지만, 지금은 리스트가 여러 값을 담는 상자라고 이해해두면 충분합니다.

while 문 — 조건이 참인 동안

반복 횟수를 미리 모를 때 사용합니다. 조건이 참인 동안 계속 반복합니다.

void main() {
  int count = 1;

  while (count <= 5) {
    print('현재 카운트: $count');
    count++;
  }
}

count가 5를 넘는 순간 조건이 거짓이 되어 반복을 멈춥니다. 주의할 점은 반복문 내부에서 조건이 결국 거짓이 되도록 값을 변경해줘야 한다는 것입니다. 그렇지 않으면 프로그램이 영원히 멈추지 않는 무한 루프에 빠집니다.

실용적인 예로, 숫자를 절반씩 줄여가며 1 이하가 될 때까지 반복해봅시다.

void main() {
  double value = 100.0;

  while (value > 1) {
    print('값: $value');
    value /= 2;
  }
  print('최종값: $value');
}

do-while 문 — 최소 한 번은 실행

while은 처음부터 조건을 확인합니다. 반면 do-while은 일단 한 번 실행하고 그 다음에 조건을 확인합니다.

void main() {
  int number = 10;

  do {
    print('number = $number');
    number--;
  } while (number > 0);
}

조건이 처음부터 거짓이어도 블록이 최소 한 번은 실행됩니다. 사용자에게 입력을 받을 때처럼 "일단 해보고 조건 확인"이 필요한 상황에 적합합니다.

break — 반복 탈출

반복 중간에 특정 조건이 충족되면 즉시 반복을 멈추고 싶을 때 break를 사용합니다.

void main() {
  for (int i = 1; i <= 10; i++) {
    if (i == 5) {
      print('5에서 멈춥니다.');
      break;
    }
    print(i);
  }
}

실행 결과입니다.

1
2
3
4
5에서 멈춥니다.

break는 자신이 속한 가장 안쪽 반복문 하나만 탈출합니다.

continue — 현재 반복 건너뛰기

이번 반복만 건너뛰고 다음 반복으로 넘어가고 싶을 때는 continue를 사용합니다.

void main() {
  for (int i = 1; i <= 10; i++) {
    if (i % 2 == 0) {
      continue; // 짝수는 건너뜀
    }
    print(i); // 홀수만 출력
  }
}

실행 결과입니다.

1
3
5
7
9

레이블 — 중첩 반복 제어

반복문 안에 또 다른 반복문이 있을 때, breakcontinue는 가장 안쪽 반복에만 작용합니다. 바깥쪽 반복까지 제어하려면 레이블을 사용합니다.

void main() {
  outerLoop: // 레이블 선언
  for (int i = 1; i <= 3; i++) {
    for (int j = 1; j <= 3; j++) {
      if (j == 2) {
        continue outerLoop; // 바깥 반복으로 continue
      }
      print('i=$i, j=$j');
    }
  }
}

실행 결과입니다.

i=1, j=1
i=2, j=1
i=3, j=1

j가 2가 되는 순간 outerLoop 레이블을 향한 continue가 실행되어 바깥쪽 for의 다음 반복으로 넘어갑니다. j=2j=3은 건너뜁니다.

레이블은 강력하지만 코드 흐름을 복잡하게 만들 수 있습니다. 꼭 필요할 때만 사용하는 것이 좋습니다.

전체 예제 — 구구단 출력기

배운 반복문을 조합해 구구단을 출력해봅시다.

void main() {
  for (int i = 2; i <= 9; i++) {
    print('--- $i단 ---');
    for (int j = 1; j <= 9; j++) {
      print('$i × $j = ${i * j}');
    }
  }
}

중첩된 for 문으로 2단부터 9단까지 모든 구구단을 출력합니다. 바깥 반복은 단을, 안쪽 반복은 곱할 숫자를 담당합니다.

다음 챕터에서는 이 반복문 안에 담을 수 있는 함수를 배웁니다. 코드에 이름을 붙여 재사용하는 방법, 그리고 Dart에서 함수가 어떤 의미를 갖는지 알아봅시다.