숏컷 코드
cpp
// 인덱스 기반 — 위치가 필요할 때
for (int i = 0; i < n; ++i) { ... }
// range-based for — 컨테이너 순회
for (const auto& item : collection) { ... }
// 조건 기반 — 종료 시점이 조건에 의존
while (!queue.empty()) { process(queue.front()); queue.pop(); }
// 최소 한 번 실행 보장
do { line = read(); } while (!line.empty());반복문 카드는 "인덱스가 필요한가", "원소만 순회하면 되는가", "반복 횟수를 모르나"부터 나누면 읽기 쉽습니다.
문법
먼저 다시 보는 기본형은 아래입니다.
- 인덱스 기반:
for (int i = 0; i < n; ++i) - 컨테이너 순회:
for (const auto& x : container) - 조건 기반 반복:
while (cond) - 최소 한 번 실행:
do { ... } while (cond);
인덱스 for — 위치와 범위가 필요할 때
전통적인 for는 인덱스로 두 컨테이너를 동시에 순회하거나, 역방향 순회, 특정 위치 원소를 수정할 때 씁니다.
cpp
// 두 배열 동시 순회
for (int i = 0; i < n; ++i) {
result[i] = a[i] + b[i];
}
// 역방향 — 부호 있는 인덱스가 필요한 이유
for (int i = n - 1; i >= 0; --i) { ... }
// ❌ size_t i = n-1; i >= 0 — size_t는 부호 없음, 0 아래로 감싸(wrap)
// 인덱스를 써야 하는 이유가 없다면 range-for가 더 명확range-based for — 의도가 명확한 컨테이너 순회
컨테이너의 모든 원소를 순회할 때 range-based for는 begin()/end() 호출을 숨기고 "이 컬렉션의 원소를 처리한다"는 의도를 코드 첫 줄에 드러냅니다.
cpp
std::vector<std::string> names{"Mina", "Jin", "Soo"};
// 값 복사 — 원소마다 string 복사 발생
for (auto name : names) { ... }
// 읽기 전용 참조 — 복사 없음 (권장)
for (const auto& name : names) { ... }
// 수정 필요 시 — 참조
for (auto& name : names) {
name += "!";
}cpp
// ❌ 큰 객체를 값으로 순회하면 복사 비용이 숨어든다
for (auto item : names) { ... }
// ✅ 읽기 전용이면 const reference가 기본
for (const auto& item : names) { ... }while과 do-while — 종료 조건이 반복 횟수보다 중요할 때
반복 횟수를 미리 알 수 없고 조건이 만족되는 동안 계속 처리해야 할 때 while이 적합합니다. do-while은 최소 한 번은 반드시 실행해야 할 때 씁니다.
cpp
// while — 입력이 빌 때까지 처리
std::string line;
while (std::getline(std::cin, line)) {
process(line);
}
// do-while — 메뉴: 최소 한 번은 표시
int choice;
do {
show_menu();
std::cin >> choice;
} while (choice < 1 || choice > 4);break와 중첩 루프 탈출
break는 가장 안쪽 루프만 탈출합니다. 중첩 루프 전체를 탈출하려면 플래그 변수나 람다를 씁니다.
cpp
// ❌ break는 안쪽 for만 탈출
bool found = false;
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
if (grid[i][j] == target) {
found = true;
break; // 안쪽 for만 탈출
}
}
if (found) break; // 플래그로 바깥 for 탈출
}
// ✅ 람다로 간결하게
auto find_pos = [&]() -> std::pair<int,int> {
for (int i = 0; i < rows; ++i)
for (int j = 0; j < cols; ++j)
if (grid[i][j] == target) return {i, j};
return {-1, -1};
};
auto [r, c] = find_pos();체크포인트
- 인덱스 접근 또는 두 배열 동시 순회: 전통적
for - 컨테이너 전체 읽기:
for (const auto& x : c) - 컨테이너 원소 수정:
for (auto& x : c) - 종료 조건이 반복 횟수보다 중요:
while - 최소 한 번 실행 보장:
do-while - 중첩 루프 전체 탈출: 람다 또는 플래그 변수
주의할 점
역방향 루프에서 size_t 인덱스를 쓰면 0 아래로 감싸(wrap) 무한 루프가 됩니다.
cpp
std::vector<int> v{1, 2, 3};
// ❌ size_t는 부호 없음 — 0에서 -- 하면 최대값으로 감쌈
for (size_t i = v.size() - 1; i >= 0; --i) { // 무한 루프!
std::cout << v[i];
}
// ✅ 부호 있는 int 사용
for (int i = (int)v.size() - 1; i >= 0; --i) {
std::cout << v[i];
}
// ✅ 또는 역방향 반복자
for (auto it = v.rbegin(); it != v.rend(); ++it) {
std::cout << *it;
}참고 링크
1 sources