icon
4장 : 제어문

for 반복문

프로그램이 특정 작업을 반복적으로 수행해야 할 때 사용하는 강력한 도구인 반복문(Loop Statements) 에 대해 알아보겠습니다.

예를 들어 "1부터 100까지의 숫자를 모두 더하기", "사용자가 '종료'를 입력할 때까지 계속 입력받기", "배열의 모든 요소 출력하기"와 같은 작업들은 반복문 없이는 매우 비효율적이고 비실용적입니다.

이 장에서는 가장 널리 사용되고 강력한 반복문 중 하나인 for에 대해 자세히 살펴보겠습니다.


반복문이란 무엇인가?

반복문은 프로그램의 특정 코드 블록을 여러 번 실행하도록 지시하는 제어문입니다.

반복문은 다음과 같은 주요 구성 요소를 가집니다.

  1. 초기화 (Initialization): 반복을 시작하기 전에 한 번만 수행되는 작업 (예: 반복 횟수를 세는 변수 초기화).
  2. 조건 (Condition): 반복을 계속할지 여부를 결정하는 조건입니다. 이 조건이 true인 동안 반복이 계속됩니다. false가 되면 반복이 종료됩니다.
  3. 증감 (Increment/Decrement): 한 번의 반복(Iteration)이 끝날 때마다 수행되는 작업 (예: 반복 횟수 변수를 증가 또는 감소).
  4. 반복 몸체 (Loop Body): 조건이 참일 때 반복적으로 실행될 코드 블록입니다.

C++은 for, while, do-while의 세 가지 주요 반복문을 제공합니다. 이 장에서는 for 문을 집중적으로 다룹니다.


for 문: 정해진 횟수만큼 반복

for 문은 특히 반복 횟수가 명확하거나, 일정한 규칙에 따라 반복을 제어해야 할 때 가장 적합하게 사용됩니다.

대부분의 경우, 루프 변수를 사용하여 반복 횟수를 추적합니다.

for 문 형식
for (초기화; 조건; 증감) {
    // 조건이 true인 동안 반복적으로 실행할 코드
}
  • 초기화: for 문이 시작될 때 단 한 번 실행됩니다. 주로 루프 제어 변수를 선언하고 초기화하는 데 사용됩니다. (예: int i = 0;)
  • 조건: 매 반복이 시작되기 전에 평가됩니다. 이 조건true이면 반복 몸체가 실행되고, false이면 for 문이 종료됩니다. (예: i < 10;)
  • 증감: 각 반복이 끝날 때마다 (반복 몸체가 실행된 후) 실행됩니다. 주로 루프 제어 변수의 값을 변경하여 조건을 언젠가 false로 만들도록 합니다. (예: i++, i += 2;)
  • { } (중괄호): 조건이 참일 때 실행될 코드 블록입니다. 한 줄의 코드만 실행할 경우 생략할 수 있지만, 조건문과 마찬가지로 항상 사용하는 것이 좋습니다.

for 문의 실행 흐름

  1. 초기화 부분이 실행됩니다. (딱 한 번)
  2. 조건 부분이 평가됩니다.
  3. 만약 조건true이면, for 문의 반복 몸체({ } 안의 코드)가 실행됩니다.
  4. 반복 몸체 실행이 끝나면, 증감 부분이 실행됩니다.
  5. 다시 2번 단계로 돌아가 조건 부분을 평가합니다.
  6. 조건false가 될 때까지 3, 4, 5번 과정을 반복합니다.
  7. 조건false가 되면 for 문이 종료되고 다음 코드가 실행됩니다.
1부터 5까지 출력하기
#include <iostream>

int main() {
    // i를 1로 초기화하고, i가 5보다 작거나 같을 때까지 i를 1씩 증가시키며 반복
    for (int i = 1; i <= 5; ++i) {
        std::cout << i << " "; // 1 2 3 4 5
    }
    std::cout << std::endl;

    return 0;
}
짝수만 출력하기
#include <iostream>

int main() {
    for (int i = 2; i <= 10; i += 2) { // i를 2부터 시작하여 2씩 증가
        std::cout << i << " "; // 2 4 6 8 10
    }
    std::cout << std::endl;

    return 0;
}
역순으로 출력하기
#include <iostream>

int main() {
    for (int i = 5; i >= 1; --i) { // i를 5부터 시작하여 1씩 감소
        std::cout << i << " "; // 5 4 3 2 1
    }
    std::cout << std::endl;

    return 0;
}

for 문의 다양한 활용

for 문은 그 유연성 때문에 다양한 방식으로 활용될 수 있습니다.

1. 여러 변수 초기화 및 증감 (콤마 연산자 활용): 콤마 연산자(,)를 사용하여 초기화나 증감 부분에서 여러 개의 표현식을 사용할 수 있습니다.

여러 변수 초기화 및 증감 예시
#include <iostream>

int main() {
    for (int i = 0, j = 10; i < 5; ++i, --j) {
        std::cout << "i: " << i << ", j: " << j << std::endl;
    }
    /* 출력:
    i: 0, j: 10
    i: 1, j: 9
    i: 2, j: 8
    i: 3, j: 7
    i: 4, j: 6
    */
    return 0;
}

2. 초기화, 조건, 증감 부분 생략: 필요에 따라 for 문의 각 부분을 생략할 수 있습니다. 단, 세미콜론(;)은 반드시 유지해야 합니다.

  • 초기화 생략: 루프 변수가 이미 이전에 선언 및 초기화된 경우.
  • 조건 생략: 무한 루프를 만들 때 (이 경우 break 문으로 루프를 종료해야 함).
  • 증감 생략: 반복 몸체 내에서 루프 변수를 변경할 경우.
초기화, 조건, 증감 생략 예시
#include <iostream>

int main() {
    int count = 0; // 초기화 부분 생략
    for ( ; count < 3; ++count) {
        std::cout << "Count: " << count << std::endl;
    }

    std::cout << "--- 무한 루프 예시 (break로 탈출) ---" << std::endl;
    int limit = 0;
    for ( ; ; ) { // 조건과 증감 모두 생략 -> 무한 루프
        std::cout << "Current limit: " << limit << std::endl;
        limit++;
        if (limit >= 3) {
            break; // limit이 3이 되면 루프 탈출
        }
    }

    return 0;
}

3. 중첩 for 문 (Nested for Loops): 하나의 for 문 안에 다른 for 문을 포함하여 다차원적인 반복을 수행할 수 있습니다. 주로 2차원 배열 처리나 패턴 출력 등에 사용됩니다.

중첩 for 문 예시
#include <iostream>

int main() {
    // 구구단 2단부터 9단까지 출력
    for (int i = 2; i <= 9; ++i) { // 바깥 루프: 단 (2단, 3단, ...)
        std::cout << "--- " << i << "단 ---" << std::endl;
        for (int j = 1; j <= 9; ++j) { // 안쪽 루프: 각 단의 곱셈
            std::cout << i << " * " << j << " = " << (i * j) << std::endl;
        }
        std::cout << std::endl; // 각 단 출력 후 한 줄 띄기
    }

    // 별(*) 패턴 출력
    for (int row = 0; row < 5; ++row) { // 5줄 반복
        for (int col = 0; col <= row; ++col) { // 각 줄마다 row+1개의 별 출력
            std::cout << "*";
        }
        std::cout << std::endl; // 한 줄 출력 후 줄바꿈
    }
    /* 출력:
    *
    **
    ***
    ****
    *****
    */
    return 0;
}

범위 기반 for 문 - C++11 이후

C++11 표준부터는 배열이나 컨테이너의 모든 요소를 순회할 때 코드를 훨씬 간결하게 작성할 수 있는 범위 기반 for 문(Range-based for loop) 이 도입되었습니다.

범위 기반 for 문 형식
for (요소_타입 변수_이름 : 범위) {
    // 범위의 각 요소에 대해 실행할 코드
}
  • 요소_타입 변수_이름: 범위에 있는 각 요소를 담을 변수의 타입과 이름입니다. 보통 auto 키워드를 사용하여 컴파일러가 타입을 추론하도록 합니다. 요소를 직접 변경하려면 요소_타입& 변수_이름과 같이 참조를 사용해야 합니다.
  • 범위: 배열, std::vector, std::string 등과 같이 반복 가능한(iterable) 객체입니다.
범위 기반 for 문 예시
#include <iostream>
#include <vector> // std::vector를 사용하기 위해 포함

int main() {
    int numbers[] = {10, 20, 30, 40, 50}; // C-스타일 배열

    // 배열의 모든 요소 출력
    for (int num : numbers) {
        std::cout << num << " "; // 10 20 30 40 50
    }
    std::cout << std::endl;

    std::vector<std::string> fruits = {"Apple", "Banana", "Cherry"}; // 벡터 (컨테이너)

    // 벡터의 모든 요소 출력
    for (const std::string& fruit : fruits) { // 요소를 변경하지 않을 것이므로 const 참조 사용
        std::cout << fruit << " "; // Apple Banana Cherry
    }
    std::cout << std::endl;

    // 요소 값 변경 예시
    for (int& num : numbers) { // 참조(&)를 사용하여 실제 배열 요소에 접근
        num += 1; // 각 숫자에 1을 더함
    }
    // 변경된 배열 출력
    for (int num : numbers) {
        std::cout << num << " "; // 11 21 31 41 51
    }
    std::cout << std::endl;

    return 0;
}

범위 기반 for 문은 코드의 가독성을 크게 높이고, 인덱스 오류를 줄여주므로 배열이나 컨테이너를 순회할 때 일반 for 문보다 선호됩니다.