프로젝트 1: 사칙연산 계산기

프로젝트 1: 사칙연산 계산기

학습 목표

이 프로젝트를 통해 배우는 내용: - 사용자 입력 받기 (scanf) - 조건 분기 (switch-case) - 함수 정의와 호출 - 에러 처리


1단계: 기본 계산기

요구사항

두 수와 연산자를 입력받아 결과 출력
예: 10 + 5 → 결과: 15

핵심 문법: scanf

#include <stdio.h>

int main(void) {
    int num;
    printf("숫자를 입력하세요: ");
    scanf("%d", &num);        // & 필수! (주소 전달)
    printf("입력한 숫자: %d\n", num);

    // 여러 값 입력
    int a, b;
    printf("두 숫자 입력 (공백 구분): ");
    scanf("%d %d", &a, &b);
    printf("a=%d, b=%d\n", a, b);

    // 문자 입력
    char op;
    printf("연산자 입력: ");
    scanf(" %c", &op);        // %c 앞 공백: 이전 개행문자 무시
    printf("연산자: %c\n", op);

    return 0;
}

핵심 문법: switch-case

char grade = 'B';

switch (grade) {
    case 'A':
        printf("우수\n");
        break;
    case 'B':
        printf("양호\n");
        break;
    case 'C':
        printf("보통\n");
        break;
    default:
        printf("기타\n");
        break;
}

구현

// calculator_v1.c
#include <stdio.h>

int main(void) {
    double num1, num2;
    char operator;

    printf("=== 간단한 계산기 ===\n");
    printf("계산식 입력 (예: 10 + 5): ");
    scanf("%lf %c %lf", &num1, &operator, &num2);

    double result;

    switch (operator) {
        case '+':
            result = num1 + num2;
            break;
        case '-':
            result = num1 - num2;
            break;
        case '*':
            result = num1 * num2;
            break;
        case '/':
            result = num1 / num2;
            break;
        default:
            printf("오류: 지원하지 않는 연산자입니다.\n");
            return 1;
    }

    printf("결과: %.2f %c %.2f = %.2f\n", num1, operator, num2, result);

    return 0;
}

실행 예시

$ ./calculator_v1
=== 간단한 계산기 ===
계산식 입력 (예: 10 + 5): 10 + 5
결과: 10.00 + 5.00 = 15.00

$ ./calculator_v1
계산식 입력 (예: 10 + 5): 20 / 4
결과: 20.00 / 4.00 = 5.00

2단계: 에러 처리 추가

문제점

20 / 0  결과: inf (무한대) 또는 에러

개선된 코드

// calculator_v2.c
#include <stdio.h>

int main(void) {
    double num1, num2;
    char operator;

    printf("=== 계산기 v2 ===\n");
    printf("계산식 입력 (예: 10 + 5): ");

    // 입력 검증
    if (scanf("%lf %c %lf", &num1, &operator, &num2) != 3) {
        printf("오류: 잘못된 입력 형식입니다.\n");
        return 1;
    }

    double result;
    int error = 0;

    switch (operator) {
        case '+':
            result = num1 + num2;
            break;
        case '-':
            result = num1 - num2;
            break;
        case '*':
            result = num1 * num2;
            break;
        case '/':
            if (num2 == 0) {
                printf("오류: 0으로 나눌 수 없습니다.\n");
                error = 1;
            } else {
                result = num1 / num2;
            }
            break;
        default:
            printf("오류: '%c'는 지원하지 않는 연산자입니다.\n", operator);
            error = 1;
            break;
    }

    if (!error) {
        printf("결과: %.2f %c %.2f = %.2f\n", num1, operator, num2, result);
    }

    return error;
}

3단계: 함수로 분리

구조

main() → get_input() → 입력 받기
       → calculate() → 계산 수행
       → 결과 출력

완성 코드

// calculator_v3.c
#include <stdio.h>

// 함수 선언
int get_input(double *num1, char *op, double *num2);
int calculate(double num1, char op, double num2, double *result);
void print_result(double num1, char op, double num2, double result);

int main(void) {
    double num1, num2, result;
    char operator;

    printf("=== 계산기 v3 ===\n");

    // 입력 받기
    if (get_input(&num1, &operator, &num2) != 0) {
        printf("오류: 입력 형식이 잘못되었습니다.\n");
        return 1;
    }

    // 계산
    if (calculate(num1, operator, num2, &result) != 0) {
        return 1;
    }

    // 결과 출력
    print_result(num1, operator, num2, result);

    return 0;
}

// 입력 함수
int get_input(double *num1, char *op, double *num2) {
    printf("계산식 입력 (예: 10 + 5): ");
    if (scanf("%lf %c %lf", num1, op, num2) != 3) {
        return -1;  // 에러
    }
    return 0;  // 성공
}

// 계산 함수
int calculate(double num1, char op, double num2, double *result) {
    switch (op) {
        case '+':
            *result = num1 + num2;
            break;
        case '-':
            *result = num1 - num2;
            break;
        case '*':
            *result = num1 * num2;
            break;
        case '/':
            if (num2 == 0) {
                printf("오류: 0으로 나눌 수 없습니다.\n");
                return -1;
            }
            *result = num1 / num2;
            break;
        case '%':
            // 정수 나머지 연산
            if (num2 == 0) {
                printf("오류: 0으로 나눌 수 없습니다.\n");
                return -1;
            }
            *result = (int)num1 % (int)num2;
            break;
        default:
            printf("오류: '%c'는 지원하지 않는 연산자입니다.\n", op);
            return -1;
    }
    return 0;
}

// 출력 함수
void print_result(double num1, char op, double num2, double result) {
    printf("결과: %.2f %c %.2f = %.2f\n", num1, op, num2, result);
}

4단계: 반복 계산 (최종 버전)

완성 코드

// calculator.c (최종)
#include <stdio.h>
#include <stdlib.h>

// 함수 선언
int get_input(double *num1, char *op, double *num2);
int calculate(double num1, char op, double num2, double *result);
void print_result(double num1, char op, double num2, double result);
void print_help(void);
void clear_input_buffer(void);

int main(void) {
    double num1, num2, result;
    char operator;
    char continue_calc;

    printf("=============================\n");
    printf("       간단한 계산기 v4      \n");
    printf("=============================\n");
    print_help();

    do {
        // 입력 받기
        if (get_input(&num1, &operator, &num2) != 0) {
            printf("오류: 입력 형식이 잘못되었습니다.\n");
            clear_input_buffer();
            continue;
        }

        // 계산
        if (calculate(num1, operator, num2, &result) == 0) {
            // 결과 출력
            print_result(num1, operator, num2, result);
        }

        // 계속 여부
        printf("\n계속하시겠습니까? (y/n): ");
        scanf(" %c", &continue_calc);
        clear_input_buffer();
        printf("\n");

    } while (continue_calc == 'y' || continue_calc == 'Y');

    printf("계산기를 종료합니다.\n");
    return 0;
}

int get_input(double *num1, char *op, double *num2) {
    printf("\n계산식 입력: ");
    if (scanf("%lf %c %lf", num1, op, num2) != 3) {
        return -1;
    }
    return 0;
}

int calculate(double num1, char op, double num2, double *result) {
    switch (op) {
        case '+':
            *result = num1 + num2;
            break;
        case '-':
            *result = num1 - num2;
            break;
        case '*':
        case 'x':
        case 'X':
            *result = num1 * num2;
            break;
        case '/':
            if (num2 == 0) {
                printf("오류: 0으로 나눌 수 없습니다.\n");
                return -1;
            }
            *result = num1 / num2;
            break;
        case '%':
            if (num2 == 0) {
                printf("오류: 0으로 나눌 수 없습니다.\n");
                return -1;
            }
            *result = (int)num1 % (int)num2;
            break;
        case '^':
            // 간단한 거듭제곱 (양의 정수만)
            *result = 1;
            for (int i = 0; i < (int)num2; i++) {
                *result *= num1;
            }
            break;
        default:
            printf("오류: '%c'는 지원하지 않는 연산자입니다.\n", op);
            return -1;
    }
    return 0;
}

void print_result(double num1, char op, double num2, double result) {
    printf(">>> %.4g %c %.4g = %.4g\n", num1, op, num2, result);
}

void print_help(void) {
    printf("\n지원 연산자: + - * / %% ^\n");
    printf("입력 형식: 숫자 연산자 숫자\n");
    printf("예시: 10 + 5, 20 / 4, 2 ^ 10\n");
}

void clear_input_buffer(void) {
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
}

실행 예시

=============================
       간단한 계산기 v4
=============================

지원 연산자: + - * / % ^
입력 형식: 숫자 연산자 숫자
예시: 10 + 5, 20 / 4, 2 ^ 10

계산식 입력: 100 + 250
>>> 100 + 250 = 350

계속하시겠습니까? (y/n): y

계산식 입력: 2 ^ 10
>>> 2 ^ 10 = 1024

계속하시겠습니까? (y/n): y

계산식 입력: 10 / 0
오류: 0으로 나눌 수 없습니다.

계속하시겠습니까? (y/n): n

계산기를 종료합니다.

컴파일 및 실행

# 컴파일
gcc -Wall -Wextra -std=c11 calculator.c -o calculator

# 실행
./calculator

배운 내용 정리

개념 설명
scanf 형식에 맞게 입력 받기
switch-case 값에 따른 분기 처리
함수 분리 코드 구조화, 재사용성
포인터 매개변수 함수에서 값 변경하기
에러 처리 반환값으로 성공/실패 표시

연습 문제

  1. 제곱근 연산 추가: sqrt 연산자 추가 (힌트: #include <math.h>, sqrt())

  2. 계산 이력 저장: 최근 10개 계산 결과를 배열에 저장하고 출력하는 기능 추가

  3. 괄호 지원: (10 + 5) * 2 같은 수식 처리 (어려움 주의!)


다음 단계

04_Project_Number_Guessing.md → 게임을 만들어봅시다!

to navigate between lessons