C언어 - 코드 분석 연습 (기본 예제)

1. C언어 코드 분석 연습

  • 언어와 마찬가지로 프로그래밍 코드 역시 작성 능력뿐만 아니라 읽는 능력도 중요하다.
  • 코드를 읽는 능력은 프로그래밍 과정에서 발생하는 버그를 발견하고, 코드의 동작을 미리 예측하는 분석 능력의 기초가 된다.
  • 아래에 제시된 코드를 컴파일하지 않고 직접 분석하여 실행 결과를 예측해 보자.
  • 이를 통해 코드 이해 능력을 기르고, 논리적으로 사고하는 연습을 할 수 있다.

1.1. 초급 난이도

1.1.1. ex01_low_if.c

  • if/else 조건문의 제어 흐름을 이해한다.
  • a + b > c * 3 식에서 연산자 우선순위를 확인한다.
  • const로 선언된 상수 값이 조건 판단에 어떻게 사용되는지를 추적한다.
#include <stdio.h>
 
int main(void)
{
    const int a = 3;
    const int b = 5;
    const int c = 2;
 
    int result = 0;
 
    if (a + b > c * 3) {
        result = 1;
    } else {
        result = 2;
    }
 
    printf("%d\n", result);
    return 0;
}

1.1.2. ex02_low_while_sum.c

  • while 반복문을 이용하여 값을 누적하는 과정을 이해한다.
  • #define MAX_NUM으로 정의된 반복 종료 조건을 확인한다.
  • 각 반복 회차에서 sum 값이 어떻게 증가하는지를 추적한다.
#include <stdio.h>
 
#define MAX_NUM     5
 
int main(void)
{
    int i = 1;
    int sum = 0;
 
    while (i <= MAX_NUM) {
        sum = sum + i;
        i = i + 1;
    }
 
    printf("%d\n", sum);
    return 0;
}

1.1.3. ex03_low_switch.c

  • switch/case 문과 이후에 실행되는 if/else 문의 흐름을 이해한다.
  • const로 정의된 n 값에 따라 선택되는 case와, 이후 score 값의 변경 과정을 추적한다.
#include <stdio.h>
 
int main(void) {
    const int n = 4;
    int score = 0;
 
    switch (n % 3) {
        case 0:
            score = 10;
            break;
        case 1:
            score = 20;
            break;
        default:
            score = 30;
            break;
    }
 
    if (score > 15) {
        score = score - 5;
    } else {
        score = score + 5;
    }
 
    printf("%d\n", score);
    return 0;
}

1.1.4. ex04_low_nested_if.c

  • 중첩 반복문 구조와 이를 이용한 약수 개수 계산 과정을 이해한다.
  • count == 2 조건을 통해 소수를 판별하는 방식과 sum 값의 누적 변화를 추적한다.
#include <stdio.h>
 
int main(void)
{
    const int x = 7;
    const int y = 4;
    int out = 0;
 
    if (x > y) {
        if ((x - y) % 2 == 1) {
            out = 9;
        } else {
            out = 6;
        }
    } else {
        out = 3;
    }
 
    printf("%d\n", out);
    return 0;
}

1.2. 중급 난이도

1.2.1. ex05_mid_for_break.c

  • break 문에 의해 for 반복문이 중단되는 흐름을 이해한다.
  • #define LOOP_MAX, #define THRESHOLD 상수를 사용한 조건 판단 과정을 확인한다.
#include <stdio.h>
 
#define LOOP_MAX    10
#define THRESHOLD   20
 
int main(void)
{
    int i;
    int answer = 0;
 
    for (i = 1; i <= LOOP_MAX; i = i + 1) {
        if (i * i > THRESHOLD) {
            answer = i;
            break;
        }
    }
 
    printf("%d\n", answer);
    return 0;
}

1.2.2. ex06_mid_function_chain.c

  • 함수 호출에 따른 값의 변환 과정을 이해한다.
  • transform() 함수를 두 번 연속 호출할 때, 입력 값과 반환 값이 어떻게 변화하는지를 추적한다.
#include <stdio.h>
 
int transform(int n)
{
    int v = n;
 
    if (v % 2 == 0) {
        v = v / 2;
    } else {
        v = v * 3 + 1;
    }
 
    return v - 1;
}
 
int main(void)
{
    int x = 6;
 
    x = transform(x);
    x = transform(x);
 
    printf("%d\n", x);
    return 0;
}

1.2.3. ex07_mid_do_while_reverse.c

  • do/while 반복문과 숫자 자릿수 처리 방식을 이해한다.
  • init_n 값에서 시작하여, 오른쪽 자릿수부터 처리되며 reversed 값이 갱신되는 과정을 추적한다.
#include <stdio.h>
 
int main(void)
{
    const int init_n = 321;
 
    int n = init_n;
    int reversed = 0;
 
    do {
        reversed = reversed * 10 + (n % 10);
        n = n / 10;
    } while (n > 0);
 
    printf("%d\n", reversed);
    return 0;
}

1.3. 고급 난이도

1.3.1. ex08_high_prime_sum.c

  • 중첩된 반복문 구조와 이를 이용한 약수 개수 계산 과정을 이해한다.
  • count == 2일 때(소수를 판별하는 조건)와 sum 변수의 변화를 추적한다.
#include <stdio.h>
 
int main(void)
{
    int n;
    int sum = 0;
 
    for (n = 1; n <= 6; n = n + 1) {
        int d;
        int count = 0;
 
        for (d = 1; d <= n; d = d + 1) {
            if (n % d == 0) {
                count = count + 1;
            }
        }
 
        if (count == 2) {
            sum = sum + n;
        }
    }
 
    printf("%d\n", sum);
    return 0;
}

1.3.2. ex09_high_recursion.c

  • 재귀 함수의 호출 방식을 이해한다.
  • INITIAL_VAL에서 시작하여 calc() 호출 시 콜 스택의 흐름과 짝수/홀수 분기 동작을 추적한다.
#include <stdio.h>
 
#define INITIAL_VAL     6
 
int calc(int n)
{
    if (n <= 1) {
        return 1;
    }
 
    if (n % 2 == 0) {
        return n + calc(n - 1);
    }
 
    return calc(n - 1);
}
 
int main(void)
{
    printf("%d\n", calc(INITIAL_VAL));
    return 0;
}

1.3.3. ex10_high_state_flow.c

  • 상태 기반 제어 흐름(State-based Control Flow)을 이해한다.
  • 반복문 내부에서 state 값의 전환에 따라 n 값이 어떻게 변화하는지를 추적한다.
#include <stdio.h>
 
int main(void)
{
    int n = 23;
    int state = 0;
    int steps = 0;
 
    while (n > 0) {
        if (state == 0) {
            n = n - 2;
            state = 1;
        } else if (state == 1) {
            n = n / 2;
            state = 2;
        } else {
            n = n - 1;
            state = 0;
        }
 
        steps = steps + 1;
    }
 
    printf("%d\n", steps);
    return 0;
}