for 반복문
프로그램이 특정 작업을 반복적으로 수행해야 할 때 사용하는 강력한 도구인 반복문(Loop Statements) 에 대해 알아보겠습니다.
예를 들어 "1부터 100까지의 숫자를 모두 더하기", "사용자가 '종료'를 입력할 때까지 계속 입력받기", "배열의 모든 요소 출력하기"와 같은 작업들은 반복문 없이는 매우 비효율적이고 비실용적입니다.
이 장에서는 가장 널리 사용되고 강력한 반복문 중 하나인 for
문에 대해 자세히 살펴보겠습니다.
반복문이란 무엇인가?
반복문은 프로그램의 특정 코드 블록을 여러 번 실행하도록 지시하는 제어문입니다.
반복문은 다음과 같은 주요 구성 요소를 가집니다.
- 초기화 (Initialization): 반복을 시작하기 전에 한 번만 수행되는 작업 (예: 반복 횟수를 세는 변수 초기화).
- 조건 (Condition): 반복을 계속할지 여부를 결정하는 조건입니다. 이 조건이
true
인 동안 반복이 계속됩니다.false
가 되면 반복이 종료됩니다. - 증감 (Increment/Decrement): 한 번의 반복(Iteration)이 끝날 때마다 수행되는 작업 (예: 반복 횟수 변수를 증가 또는 감소).
- 반복 몸체 (Loop Body): 조건이 참일 때 반복적으로 실행될 코드 블록입니다.
C++은 for
, while
, do-while
의 세 가지 주요 반복문을 제공합니다. 이 장에서는 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
문이 종료되고 다음 코드가 실행됩니다.
#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차원 배열 처리나 패턴 출력 등에 사용됩니다.
#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
문보다 선호됩니다.