Menu

C++ for 반복문: 문법, 예제, 흔한 실수

C++ for 반복문으로 코드를 반복하는 방법 - 세 부분으로 된 헤더, 증가·감소 카운트, 배열 순회, 중첩, break와 continue, 그리고 누구나 한 번쯤 겪는 off-by-one 및 부호 없는 타입 버그.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

왜 for 반복문인가

switch는 하나의 분기를 골라 한 번 실행합니다. 하지만 실제 프로그램은 무언가를 반복해서 해야 합니다. 모든 점수를 출력하거나, 숫자 목록을 합산하거나, 격자의 10행을 그리는 식입니다. for 반복문은 정해진 횟수만큼 코드를 반복하는 C++의 일꾼이며, 직접 제어하는 내장 카운터를 가지고 있습니다.

for 반복문에 필요한 모든 것이 하나의 간결한 헤더에 담겨 있어서, "몇 번, 어떻게"라는 전체 이야기를 한눈에 볼 수 있습니다.

세 부분으로 된 헤더

for 반복문의 헤더에는 세미콜론으로 구분된 세 부분이 있습니다. 초기화자, 조건, 갱신입니다.

for (initializer; condition; update) {
    // 본문 - 조건이 참인 동안 실행됨
}

이들은 정해진 순서로 실행됩니다. 초기화자는 시작할 때 한 번 실행됩니다. 그다음 조건은 매 반복 전에 검사됩니다. 본문은 조건이 true일 때만 실행됩니다. 그리고 갱신은 매 반복의 끝, 조건이 다시 검사되기 직전에 실행됩니다.

여기서 int i = 0은 한 번 실행됩니다. 그다음 i < 5가 검사되어, 성립하는 동안 본문이 출력하고 i++가 카운터를 올립니다. i5에 도달하면 조건이 false가 되어 반복문을 빠져나가고 done이 출력됩니다. 본문은 정확히 5번 실행되며, i0부터 4까지의 값을 가집니다.

카운터를 헤더 안에서 선언하면(int i = 0) i의 범위가 반복문 안으로 한정됩니다. 닫는 중괄호 뒤에는 존재하지 않으며, 이는 바로 우리가 원하는 바입니다.

증가, 감소, 그리고 단계별 카운트

갱신 부분은 i++에만 국한되지 않습니다. 거꾸로 셀 수도 있고, 임의의 양만큼 건너뛸 수도 있으며, 배열 인덱스를 순회할 수도 있습니다.

첫 번째 반복문은 i > 0인 동안 실행되며 매번 감소하므로 5 4 3 2 1을 출력합니다. 두 번째는 매번 2를 더하고, 10이 포함하고 싶은 값이므로 <= 10을 씁니다. 조건을 갱신과 맞추세요. 거꾸로 세기는 > 또는 >=와, 올려 세기는 < 또는 <=와 짝을 이룹니다.

배열 순회

카운트 반복문의 가장 흔한 용도는 배열을 인덱스로 훑는 것입니다. 카운터는 읽는 위치 역할도 겸합니다.

조건이 i <= n아니라 i < n이라는 점에 주목하세요. 5개짜리 배열의 유효한 인덱스는 0부터 4까지이며, 인덱스 5는 끝을 넘어섭니다. scores[5]를 읽는 것은 미정의 동작으로, 쓰레기 값을 출력하거나, 크래시가 나거나, 동작하는 것처럼 보이면서 조용히 메모리를 망가뜨릴 수 있습니다. i < n 패턴은 0부터 시작하는 모든 배열에 대한 안전한 기본값입니다.

인덱스가 아니라 값만 필요하다면 범위 기반 for가 더 깔끔합니다. 실제로 위치가 필요할 때는 고전적인 인덱스 반복문을 꺼내 쓰세요.

break와 continue

두 개의 키워드로 반복문 도중에 흐름을 바꿀 수 있습니다. break는 반복문을 즉시 빠져나갑니다. continue는 현재 반복의 나머지를 건너뛰고 갱신으로 점프합니다.

첫 번째 반복문은 7을 찾는 순간 멈추고 나머지는 검사하지 않습니다. 두 번째는 i가 짝수일 때마다 본문의 출력을 건너뛰기 위해 continue를 씁니다. 갱신 i++는 여전히 실행되므로 반복문은 계속 진행됩니다. 미묘한 함정: continue갱신으로 점프합니다. 따라서 카운터가 헤더가 아니라 본문 안에서 갱신되는 반복문에서 continue에 의존하면, 그 갱신을 실수로 건너뛰고 영원히 돌 수 있습니다.

중첩 반복문

격자, 표, 쌍을 다루려면 for를 다른 for 안에 넣습니다. 안쪽 반복문은 바깥쪽 반복문의 한 단계마다 완전히 실행됩니다.

이것은 3x3 곱셈 격자를 출력합니다. 바깥쪽 반복문이 row를 고정하고, 안쪽 반복문이 그 행의 모든 col을 훑은 다음, 줄바꿈이 행을 마무리합니다. 카운터에는 서로 다른 이름을 주세요(i/i가 아니라 row/col). 같은 이름을 재사용하면 바깥쪽을 가려서 영문 모를 버그를 만듭니다. 비용도 주의하세요. n 반복문을 n 반복문 안에 중첩하면 본문이 n * n번 실행되어 빠르게 불어납니다.

흔한 함정

몇 가지 함정이 C++의 for 반복문 버그 대부분을 차지합니다.

  • off-by-one: 0부터 시작하는 크기에서 i <= n은 끝을 넘어 한 요소를 읽습니다. i < n을 쓰세요.
  • 부호 없는 언더플로: 부호 없는 타입으로 거꾸로 세면 결코 음수가 되지 않습니다. for (size_t i = n - 1; i >= 0; i--)는 영원히 반복합니다. 부호 없는 값에 대해 i >= 0은 항상 참이기 때문입니다. i0일 때 i--는 거대한 양수로 되돌아갑니다(wrap). 내려가는 카운트에는 부호 있는 int를 쓰거나 조건을 다시 작성하세요.
  • 본문 안에서 카운터 수정: 헤더에 더해 본문에서도 i를 바꾸면 반복 횟수를 예측할 수 없게 됩니다. 한 곳을 정하세요.
// BUG: infinite loop - unsigned i is never < 0
for (size_t i = n - 1; i >= 0; i--) {
    process(arr[i]);
}

부동소수점 카운터는 또 다른 조용한 위험입니다. for (double x = 0.0; x != 1.0; x += 0.1)0.1을 정확히 저장할 수 없기 때문에 정확히 1.0에 도달하지 못할 수 있습니다. 정수 카운트로 반복하면서 값은 내부에서 계산하거나, != 대신 <를 쓰세요.

다음: while 반복문

for 반복문은 횟수를 미리 알 때 빛납니다. 하지만 때로는 고정된 단계 수 없이 조건이 바뀔 때까지 반복해야 합니다. 파일 끝까지 입력을 읽거나, 성공할 때까지 재시도하는 식입니다. 그것이 헤더를 조건 하나로 줄인 while 반복문의 역할입니다. 다음 페이지입니다.

자주 묻는 질문

C++에서 for 반복문은 어떻게 작성하나요?

헤더에 세미콜론으로 구분된 세 부분, 즉 초기화자, 조건, 갱신을 넣습니다. for (int i = 0; i < 5; i++) { cout << i; }i가 0, 1, 2, 3, 4로 바뀌면서 본문을 실행합니다. 조건이 false가 되는 즉시 반복문은 멈춥니다.

C++에서 for 반복문과 범위 기반 for 반복문의 차이는 무엇인가요?

고전적인 for는 직접 제어하는 인덱스 카운터(for (int i = 0; i < n; i++))를 줍니다. 위치가 필요하거나 사용자 정의 방식으로 진행하고 싶을 때 필요합니다. 범위 기반 for(for (int x : v))는 인덱스를 감추고 각 요소를 그대로 건네줍니다. 값만 필요할 때 더 깔끔합니다.

왜 제 C++ for 반복문이 한 번 더 또는 한 번 덜 실행되나요?

그게 바로 고전적인 off-by-one(하나 차이) 버그입니다. 0부터 시작하는 크기에서 < 대신 <=를 쓰면 반복을 한 번 더 하면서 배열의 끝을 넘어 읽습니다. 마지막 값을 포함하려 했는데 <를 쓰면 한 번 부족하게 실행됩니다. 크기가 n인 배열에서 안전한 패턴은 for (int i = 0; i < n; i++)입니다.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기