C 반복문 마스터: for, while, do-while, 제어문(break/continue/goto) 활용법
반복문은 코드 블록을 여러 번 실행하게 합니다. C는 3가지 기본 반복문과 루프 제어문을 제공합니다. 상황별 최적 선택과 패턴을 익히세요.
3대 반복문 비교
| 반복문 | 조건 검사 시점 | 최소 실행 횟수 | 적합한 상황 |
while | 루프 진입 전 (사전 검사) | 0회 | 반복 횟수 모름, 조건 기반 |
for | 루프 진입 전 (사전 검사) | 0회 | 횟수 정해짐, 카운터 필요 |
do-while | 루프 실행 후 (사후 검사) | 1회 | 최소 1회 실행 보장, 메뉴 등 |
while 문
while (조건) {
// 본문
}
패턴: 센티널 제어 루프
int sum = 0, input;
printf("숫자 입력 (0이면 종료): ");
while (scanf("%d", &input) == 1 && input != 0) {
sum += input;
}
printf("합계: %d\n", sum);
패턴: 플래그 제어
bool running = true;
while (running) {
// 작업...
if (quit_condition) running = false;
}
for 문
for (초기화; 조건; 증감) {
// 본문
}
실행 순서
- 초기화 (1회)
- 조건 검사 → 거짓이면 종료
- 본문 실행
- 증감식 실행
- 2번으로 이동
다양한 for 패턴
// 기본 카운터
for (int i = 0; i < n; i++) { ... }
// 역순
for (int i = n - 1; i >= 0; i--) { ... }
// 다중 변수 초기화/증감 (콤마 연산자)
for (int i = 0, j = n - 1; i < j; i++, j--) { ... }
// 조건만 있는 for (while 대체)
for (; *str != '\0'; str++) { ... }
// 무한 루프
for (;;) { ... }
C99 블록 스코프 루프 변수
for (int i = 0; i < 3; i++) { ... }
// i는 루프 블록 내부에서만 유효 (권장)
for (int i = 0; i < 3; i++) { ... }
for (int i = 0; i < 3; i++) { ... } // OK: 별도 스코프
do-while 문
do {
// 본문 (최소 1회 실행)
} while (조건); // 세미콜론 필수!
패턴: 메뉴/입력 검증
int choice;
do {
printf("1. 시작 2. 설정 3. 종료\n선택: ");
scanf("%d", &choice);
} while (choice < 1 || choice > 3);
중첩 루프
// 구구단
for (int i = 2; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
printf("%d x %d = %2d ", i, j, i*j);
}
printf("\n");
}
루프 제어문
break - 루프 즉시 탈출
가장 안쪽 for, while, do-while, switch만 탈출
중첩 루프에서 외부 루프 탈출하려면 플래그 또는 goto 필요
// 소수 판별 (최적화: sqrt까지)
bool is_prime(int n) {
if (n < 2) return false;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) return false; // break 대신 조기 반환
}
return true;
}
continue - 다음 반복으로 건너뛰기
// 짝수만 합산
int sum = 0;
for (int i = 1; i <= 100; i++) {
if (i % 2 != 0) continue; // 홀수 건너뛰기
sum += i;
}
goto - 레이블로 점프 (신중히 사용)
// 다중 루프 탈출 패턴
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (found) goto cleanup;
}
}
cleanup:
// 정리 코드
무한 루프와 종료
// 의도적 무한 루프
for (;;) { ... }
while (1) { ... }
do { ... } while (1);
종료: break, return, exit(), longjmp()
강제 중단: 터미널에서 Ctrl+C (SIGINT)
성능 및 모범 사례
불변 조건/계산은 루프 밖으로 끌어올리기 (Loop Invariant Code Motion)
배열 순회 시 포인터 연산 vs 인덱스: 현대 컴파일러가 동일 최적화
루프 언롤링(Unrolling)은 컴파일러에 맡기기 (-O3 등)
큰 배열 순회 시 캐시 지역성 고려: 행 우선 접근
restrict 키워드(C99)로 포인터 별칭 없음 힌트 제공