for 반복문
프로그램에서 특정 작업을 반복적으로 수행해야 할 때 핵심이 되는 도구가 반복문(Loop Statements)입니다.
예를 들어 1부터 100까지의 숫자를 모두 더하기, 사용자가 종료를 입력할 때까지 계속 입력받기, 배열의 모든 요소 출력하기와 같은 작업들은 반복문 없이는 매우 비효율적이고 비실용적입니다.
이 장에서는 가장 널리 쓰이는 반복문인 for 문을 중심으로 사용 흐름을 정리합니다.
먼저 for 문을 시작값, 계속 조건, 변화량, 본문이 맞물려 도는 반복 사이클로 봅니다.
반복문이란 무엇인가?
반복문은 프로그램의 특정 코드 블록을 여러 번 실행하도록 지시하는 제어문입니다.
반복문은 다음과 같은 주요 구성 요소를 가집니다.
초기화 (Initialization): 반복을 시작하기 전에 한 번만 수행되는 작업 (예: 반복 횟수를 세는 변수 초기화).
조건 (Condition): 반복을 계속할지 여부를 결정하는 조건입니다. 이 조건이 true인 동안 반복이 계속됩니다. false가 되면 반복이 종료됩니다.
증감 (Increment/Decrement): 한 번의 반복(Iteration)이 끝날 때마다 수행되는 작업 (예: 반복 횟수 변수를 증가 또는 감소).
반복 몸체 (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 문의 실행 흐름
초기화 부분이 실행됩니다. (딱 한 번)
조건 부분이 평가됩니다.
만약 조건이 true이면, for 문의 반복 몸체({ } 안의 코드)가 실행됩니다.
반복 몸체 실행이 끝나면, 증감 부분이 실행됩니다.
다시 2번 단계로 돌아가 조건 부분을 평가합니다.
조건이 false가 될 때까지 3, 4, 5번 과정을 반복합니다.
조건이 false가 되면 for 문이 종료되고 다음 코드가 실행됩니다.
이 흐름은 초기화 → 조건 검사 → 본문 실행 → 증감 → 재검사 → 종료의 사이클로 읽으면 좋습니다. 특히 반복 횟수를 셀 때는 시작값, 비교 연산자, 끝값이 서로 맞는지 확인해야 off-by-one 오류를 줄일 수 있습니다.
#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 문은 그 유연성 때문에 다양한 방식으로 활용될 수 있습니다.
여러 변수 초기화 및 증감 (콤마 연산자 활용):
콤마 연산자(,)를 사용하여 초기화나 증감 부분에서 여러 개의 표현식을 사용할 수 있습니다.
#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;
}초기화, 조건, 증감 부분 생략:
필요에 따라 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;
}중첩 for 문 (Nested for Loops):
하나의 for 문 안에 다른 for 문을 포함하여 다차원적인 반복을 수행할 수 있습니다. 주로 2차원 배열 처리나 패턴 출력 등에 사용됩니다.
#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 (요소_타입 변수_이름 : 범위) {
// 범위의 각 요소에 대해 실행할 코드
}요소_타입 변수_이름: 범위에 있는 각 요소를 담을 변수의 타입과 이름입니다. 보통auto키워드를 사용하여 컴파일러가 타입을 추론하도록 합니다. 요소를 직접 변경하려면요소_타입& 변수_이름과 같이 참조를 사용해야 합니다.범위: 배열,std::vector,std::string등과 같이 반복 가능한(iterable) 객체입니다.
#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 문보다 선호됩니다.
아래 다이어그램은 for 문을 작성할 때 초기화, 조건, 증감, 본문 책임을 분리하고 일반 for와 범위 기반 for 중 무엇을 고를지 정리한 루프 설계표입니다.
아래 다이어그램은 for 반복문의 실행 순서와 일반 for, 범위 기반 for를 선택하는 기준을 한눈에 정리한 것입니다.