C언어에서의 제어 흐름: 조건, 반복, 중첩 및 응용

순차 실행 구조

기본적으로 C 프로그램은 위에서 아래로 명령문을 순서대로 실행합니다. 이는 특별한 제어문이 없을 때의 기본 동작 방식입니다.

#include <stdio.h>
int main() {
    int x = 5;
    int y = 7;
    int result = x + y;
    printf("결과: %d\n", result);  // 출력: 결과: 12
    return 0;
}

조건 분기문

실행 흐름을 조건에 따라 다른 경로로 나누는 기능을 제공합니다.

if-else 문

  • 단일 조건: 조건이 참일 경우에만 블록 실행
  • 이중 선택: 조건에 따라 두 가지 중 하나 실행
  • 다중 선택: 여러 조건을 순차적으로 평가
int score = 85;
if (score >= 90) {
    printf("A학점\n");
} else if (score >= 80) {
    printf("B학점\n");  // 이 문장이 실행됨
} else {
    printf("C학점 이하\n");
}

블록을 항상 중괄호로 감싸는 것이 실수를 줄이는 데 도움이 됩니다.

switch-case 문

정수형 또는 문자형 값에 따라 분기하는 구조입니다. 각 case 후에 break를 넣지 않으면 다음 case까지 연속 실행됩니다 (fall-through).

char grade = 'B';
switch (grade) {
    case 'A':
        printf("탁월한 성과\n");
        break;
    case 'B':
        printf("좋은 성과\n");
        break;
    case 'C':
        printf("보통\n");
        break;
    default:
        printf("재평가 필요\n");
        break;
}

여러 값에 대해 동일한 처리를 할 때는 fall-through를 의도적으로 사용할 수 있습니다.

반복문

특정 조건이 만족될 때까지 코드 블록을 반복 실행합니다.

for 루프

초기화, 조건, 증감이 한 줄에 정의되는 구조로, 반복 횟수가 명확할 때 적합합니다.

// 1부터 10까지 출력
for (int i = 1; i <= 10; i++) {
    printf("%d ", i);
}

while 루프

조건 검사를 먼저 수행하고, 참일 경우 루프 본문을 실행합니다. 반복 횟수가 사전에 불확실할 때 유용합니다.

int input;
printf("0을 입력할 때까지 반복: ");
scanf("%d", &input);
while (input != 0) {
    printf("입력값: %d\n", input);
    scanf("%d", &input);
}

do-while 루프

루프 본문을 먼저 실행한 후 조건을 검사하므로, 최소 한 번은 반드시 실행됩니다.

int value;
do {
    printf("양수를 입력하세요: ");
    scanf("%d", &value);
} while (value <= 0);

for와 while의 비교

특징 for while
사용 시나리오 반복 횟수 명확 종료 조건 중심
구조적 배치 모두 한 줄에 포함 분산되어 있음

반복문 응용 예제

6과 8로 모두 나누어지는 수 세기

int start = 1, end = 1000;
int count = 0;
for (int i = start; i <= end; i++) {
    if (i % 24 == 0) {  // LCM(6,8)=24
        count++;
    }
}
printf("총 %d개 발견\n", count);

정수 자릿수 역순 변환

int n = 789, reversed = 0;
while (n != 0) {
    reversed = reversed * 10 + (n % 10);
    n /= 10;
}
printf("역순: %d\n", reversed);  // 출력: 987

회문 정수 판별

int original = 12321;
int temp = original, rev = 0;
while (temp != 0) {
    rev = rev * 10 + (temp % 10);
    temp /= 10;
}
if (original == rev) {
    printf("%d는 회문입니다.\n", original);
}

문자열 회문 검사

#include <string.h>
char s[] = "radar";
int len = strlen(s);
int is_palindrome = 1;
for (int i = 0; i < len / 2; i++) {
    if (s[i] != s[len - i - 1]) {
        is_palindrome = 0;
        break;
    }
}
if (is_palindrome) printf("회문입니다.\n");

반복문으로 곱셈과 나눗셈 구현

// 곱셈: 덧셈의 반복
int multiply(int a, int b) {
    int result = 0;
    for (int i = 0; i < b; i++) {
        result += a;
    }
    return result;
}

// 나눗셈: 뺄셈의 반복
int divide(int dividend, int divisor) {
    int quotient = 0;
    while (dividend >= divisor) {
        dividend -= divisor;
        quotient++;
    }
    return quotient;
}

중첩 반복문

패턴 출력

// 직각삼각형
for (int row = 1; row <= 5; row++) {
    for (int col = 1; col <= row; col++) {
        printf("*");
    }
    printf("\n");
}

구구단 출력

for (int dan = 2; dan <= 9; dan++) {
    for (int mul = 1; mul <= 9; mul++) {
        printf("%d*%d=%d ", dan, mul, dan * mul);
    }
    printf("\n");
}

1부터 100까지 소수 개수 세기

int prime_count = 0;
for (int num = 2; num <= 100; num++) {
    int is_prime = 1;
    for (int factor = 2; factor * factor <= num; factor++) {
        if (num % factor == 0) {
            is_prime = 0;
            break;
        }
    }
    if (is_prime) prime_count++;
}
printf("소수 개수: %d\n", prime_count);

거듭제곱 합 계산: 1¹ + 2² + ... + 10¹⁰

long long total = 0;
for (int base = 1; base <= 10; base++) {
    long long power = 1;
    for (int exp = 1; exp <= base; exp++) {
        power *= base;
    }
    total += power;
}
printf("총합: %lld\n", total);

루프 제어와 goto

break와 continue

  • break: 현재 루프 또는 switch에서 즉시 탈출
  • continue: 현재 반복만 건너뛰고 다음 반복으로 진행
for (int i = 0; i < 10; i++) {
    if (i == 3) continue;  // 3일 때 건너뜀
    if (i == 7) break;     // 7에서 종료
    printf("%d ", i);      // 출력: 0 1 2 4 5 6
}

goto 문

라벨로 직접 점프하지만, 남용 시 코드 가독성이 급격히 저하됩니다. 다중 루프 탈출 등 극히 제한된 경우에만 고려합니다.

for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
        if (some_condition) {
            goto exit_loop;
        }
    }
}
exit_loop:
printf("다중 루프 탈출 완료\n");

완전수와 아름다운 수 찾기

아름다운 수 (Narcissistic Number)

세 자리 수 중 각 자릿수의 세제곱의 합이 그 수 자신과 같은 경우입니다.

for (int n = 100; n <= 999; n++) {
    int ones = n % 10;
    int tens = (n / 10) % 10;
    int hundreds = n / 100;
    if (n == ones*ones*ones + tens*tens*tens + hundreds*hundreds*hundreds) {
        printf("%d ", n);
    }
}

완전수 (Perfect Number)

자신을 제외한 모든 약수의 합이 그 수 자신과 같은 자연수입니다.

for (int num = 2; num <= 1000; num++) {
    int sum = 1;  // 1은 항상 약수
    for (int div = 2; div <= num / 2; div++) {
        if (num % div == 0) {
            sum += div;
        }
    }
    if (sum == num) {
        printf("%d는 완전수입니다.\n", num);
    }
}

태그: C 제어문 반복문 조건문 중첩루프

6월 24일 18:05에 게시됨