language/c

[C언어] 05. 반복문

렁치 2026. 8. 3. 16:00

같은 작업을 여러 번 해야 할 때, 코드를 여러 번 복사하는 대신 반복문을 쓴다. "1부터 100까지 더하기"를 덧셈 100줄로 쓰지 않고 몇 줄로 끝내는 것이다. C의 반복문에는 while, do~while, for 세 가지가 있다.

 

종류 특징
while 조건이 참인 동안 반복 (반복 횟수를 모를 때)
do ~ while 일단 한 번 실행한 뒤 조건 검사 (최소 1회 보장)
for 정해진 횟수만큼 반복

1. while 문

조건이 참인 동안 중괄호 안을 반복한다. 조건을 먼저 검사하므로, 처음부터 거짓이면 한 번도 실행되지 않는다(0번 이상).

while (조건) {
    수행 문장;
}

 

반복 횟수를 미리 알 수 없을 때(예: "0이 입력될 때까지") 적합하다.

int n;
while (1) {                 // 무한 루프
    scanf("%d", &n);
    if (n == 0) break;      // 0이 들어오면 탈출
    printf("%s\n", n % 2 ? "홀수" : "짝수");
}

2. do ~ while 문

while과 비슷하지만, 문장을 먼저 실행한 뒤 조건을 검사한다. 그래서 조건과 상관없이 최소 한 번은 실행된다(1번 이상).

do {
    수행 문장;
} while (조건);

 

"메뉴를 한 번은 보여주고, 계속할지 묻는다" 같은 상황처럼 "최소 한 번 실행"이 필요할 때 어울린다. while과 do~while의 차이가 "조건을 검사하는 시점"이라는 걸, 처음 조건이 거짓인 경우로 비교해보고서야 분명히 잡았다.


3. for 문

반복 횟수가 정해져 있을 때 가장 깔끔하다. 카운터 변수의 초기화·조건·증감을 한 줄에 모아 쓴다.

for (초기식; 조건식; 증감식) {
    수행 문장;
}
  • 초기식 (i = 0): 처음 한 번만 실행.
  • 조건식 (i < 5): 매 반복 전에 검사, 거짓이면 종료.
  • 증감식 (i++): 매 반복이 끝날 때 실행.

 

for (int iIndex = 0; iIndex < 9; iIndex++) {
    int iMul = iIndex + 1;
    printf("5 x %d = %d\n", iMul, 5 * iMul);   // 구구단 5단
}

 

이중 for문을 쓰면 별 삼각형 같은 2차원 패턴도 만들 수 있다.

 

for (int iLineIndex = 0; iLineIndex < 5; iLineIndex++) {       // 줄
    for (int iStarIndex = 0; iStarIndex < iLineIndex + 1; iStarIndex++)     // 각 줄의 별 개수
        printf("*");
    printf("\n");
}

 

바깥 루프가 "줄"을, 안쪽 루프가 "그 줄에 찍을 별 개수"를 담당한다는 구조를 잡으니 패턴 문제가 한결 쉬워졌다. 이중 for문이 처음엔 막막했는데, 두 루프의 역할을 분리해 보니 풀렸다.


4. 분기문: break와 continue

반복 도중 흐름을 바꾸는 두 명령이다.

 

break vs continue
  • break: 반복문 자체를 즉시 종료하고 빠져나온다. 무한 루프 탈출에 자주 쓴다.
  • continue: 현재 반복의 남은 문장만 건너뛰고, 곧장 다음 반복으로 넘어간다.

 

// 3의 배수는 제외하고 합산 (continue 활용)
int n, sum = 0;
while (1) {
    scanf("%d", &n);
    if (n < 0) break;         // 음수면 종료
    if (n % 3 == 0) continue; // 3의 배수면 합산 건너뛰고 다음 입력
    sum += n;
}
printf("3의 배수를 제외한 합: %d\n", sum);

 

break는 "루프를 끝낸다", continue는 "이번 회차만 건너뛴다"는 차이를 분명히 구분하자.


5. 수업 코드로 보는 카페 메뉴 반복

while 반복, if 종료 조건, switch 메뉴 처리가 한 번에 들어간 예제다. 메뉴를 계속 보여주다가 사용자가 0을 입력하면 종료하고, 그동안 판매한 총액을 출력한다.

int iMenuNo;
int iPriceAmericano;
int iPriceLatte;
int iPriceIceTea;
int iCountAmericano;
int iCountLatte;
int iCountIceTea;
int iTotal;

iMenuNo = 0;
iPriceAmericano = 1500;
iPriceLatte = 2000;
iPriceIceTea = 2500;
iCountAmericano = 0;
iCountLatte = 0;
iCountIceTea = 0;
iTotal = 0;

while (1)
{
    printf("1. 아메리카노 %d원\n", iPriceAmericano);
    printf("2. 카페라떼 %d원\n", iPriceLatte);
    printf("3. 아이스티 %d원\n", iPriceIceTea);
    printf("메뉴를 입력하세요(0 종료): ");
    scanf("%d", &iMenuNo);

    if (iMenuNo == 0)
    {
        break;
    }

    switch (iMenuNo)
    {
    case 1:
        iCountAmericano = iCountAmericano + 1;
        break;
    case 2:
        iCountLatte = iCountLatte + 1;
        break;
    case 3:
        iCountIceTea = iCountIceTea + 1;
        break;
    default:
        printf("없는 메뉴입니다.\n");
        break;
    }

    iTotal = iPriceAmericano * iCountAmericano
           + iPriceLatte * iCountLatte
           + iPriceIceTea * iCountIceTea;
}

printf("판매한 총 금액: %d\n", iTotal);

 

이 예제에서 반복의 흐름은 출력 → 입력 → 종료 판단 → 처리 → 누적 순서다. 특히 0은 메뉴가 아니라 종료 신호이므로, switch로 보내기 전에 먼저 검사해야 한다.

 

자릿수 뒤집기 유제

반복문 응용으로 끝자리부터 떼어 새 숫자를 만드는 문제다.

int iNo;
int iDigit;
int iReverse;

printf("정수 입력: ");
scanf("%d", &iNo);

iReverse = 0;

while (iNo > 0)
{
    iDigit = iNo % 10;
    iReverse = iReverse * 10 + iDigit;
    iNo = iNo / 10;
}

printf("뒤집은 수: %d\n", iReverse);

 

12345를 넣으면 5 → 54 → 543 → 5432 → 54321처럼 결과가 한 자리씩 쌓인다.


오늘 느낀 점

  • while·do~while·for가 결국 같은 일을 하되, "조건 검사 시점"과 "횟수를 아느냐"로 쓰임이 갈린다는 걸 알았다. 셋을 서로 바꿔 짜보니 관례의 이유가 보였다.
  • 이중 for문은 "바깥은 줄, 안쪽은 그 줄의 개수"로 역할을 나눠 보니 패턴 문제의 벽이 낮아졌다.
  • break와 continue를 같은 예제에서 한 번에 써보니, "루프 종료 vs 회차 건너뛰기"의 차이가 코드로 또렷하게 남았다.
  • 풀어서 하나씩 작성하다보면, 보이지 않던 반복 구조가 보인다.
  • C언어에서 bool타입이 없기 때문에 기호상수로 1을 TRUE로, 0을 FALSE로 선언하고 사용하면 편하다.

한 걸음 더

  • 세 반복문은 사실 서로 바꿔 쓸 수 있다. 같은 동작을 while로도 for로도 짤 수 있다. 다만 "횟수가 정해졌으면 for, 조건으로만 도는 거면 while, 최소 한 번은 돌아야 하면 do~while"이라는 관례를 따르면 코드의 의도가 잘 드러난다.
  • 무한 루프(while(1))는 잘못 쓰면 프로그램이 멈추지 않는다. 반드시 안에 break 조건이나 종료 경로가 있어야 한다. 의도적인 무한 루프(서버의 요청 대기 등)가 아니라면, 루프가 "언젠가는 끝나는지"를 늘 점검하는 습관이 필요하다.
  • 난수가 필요하면 rand()를 쓰는데, 그냥 쓰면 실행할 때마다 같은 수열이 나온다. srand(time(0))으로 현재 시간을 시드로 한 번 심어줘야 매번 다른 난수가 나온다. "숫자 맞히기" 같은 프로그램에서 이 시드 설정을 빠뜨리면 매번 같은 답이 나오는 함정에 빠진다.

'language > c' 카테고리의 다른 글

[C언어] 04. 조건문  (0) 2026.07.27
[C언어] 03. 수식과 연산자  (0) 2026.07.20
[C언어] 02. 기본 변수와 입력  (0) 2026.07.10
[C언어] 01. 첫 프로젝트  (0) 2026.06.28