티스토리 뷰

 

C언어 기본기 탄탄! 2018년 중간고사 문제 

안녕하세요, 코딩 탐험가 여러분! C언어 공부, 재미있게 하고 계신가요? 오늘은 2018학년도 2학기 기초 프로그래밍2 중간고사에 나왔던 문제들을 살펴보면서 C언어의 기본기를 다시 한번 점검하는 시간을 갖도록 할게요. 어렵게 느껴지는 부분도 있겠지만, 하나씩 풀어보면서 코딩 실력을 키워나가 봅시다!

 

 

 

목차

 

조건 연산자를 if-else로! (문제 1)

첫 번째 문제는 조건 연산자(삼항 연산자라고도 해요) `? :` 를 사용한 코드를 `if-else` 문으로 바꾸는 거예요.

// 원본 코드 (조건 연산자 사용)
void even_odd(int num) {
    printf("%s입니다.\n", (num % 2 == 0) ? "짝수" : "홀수");
}

// 변경된 코드 (if-else 사용)
void even_odd_ifelse(int num) {
    if (num % 2 == 0) { // num을 2로 나눈 나머지가 0이면 (짝수이면)
        printf("짝수입니다.\n");
    } else { // 그렇지 않으면 (홀수이면)
        printf("홀수입니다.\n");
    }
}

조건 연산자는 `(조건) ? (참일 때 값) : (거짓일 때 값)` 형태로 쓰여요. 이걸 `if-else` 문으로 바꾸면, `if (조건)` 다음에는 참일 때 실행할 코드를, `else` 다음에는 거짓일 때 실행할 코드를 넣어주면 된답니다. 두 코드는 완전히 똑같은 기능을 해요!

while문을 for문으로 변신! (문제 2)

이번에는 `while` 반복문을 `for` 반복문으로 바꿔볼까요?

// 원본 코드 (while문 사용)
i = 10;
while (i > 0) {
    printf("%d\n", i);
    --i;
}

// 변경된 코드 (for문 사용)
int i; // for문 안에서 선언해도 됩니다: for (int i = 10; ... )
for (i = 10; i > 0; --i) {
    printf("%d\n", i);
}

`for` 문은 괄호 안에 세미콜론(;)으로 구분된 세 부분이 있죠?

  1. 초기식: 반복을 시작하기 전에 딱 한 번 실행돼요. (`i = 10`)
  2. 조건식: 매 반복 시작 전에 검사해서, 참이면 반복하고 거짓이면 반복을 끝내요. (`i > 0`)
  3. 증감식: 매 반복이 끝날 때마다 실행돼요. (`--i`, 즉 i를 1 감소)

`while` 문에서는 반복 전에 초기값을 설정하고(`i = 10;`), `while` 괄호 안에 조건을 넣고(`while (i > 0)`), 반복문 내용 마지막에 증감식(`--i;`)을 넣는 것을 `for` 문은 한 줄에 깔끔하게 표현할 수 있어요.

함수의 얼굴, 함수 원형 만들기 (문제 3)

함수 `inch2cm`은 `int` 형(정수)으로 인치 값을 받아서 `double` 형(실수)으로 센티미터 값을 반환한대요. 이 함수의 '원형(prototype)'을 적어보라는 문제네요.

함수 원형은 컴파일러에게 "이런 이름과 형태를 가진 함수가 프로그램 어딘가에 있을 거야!"라고 미리 알려주는 역할을 해요. 함수를 사용하기 전에 선언해줘야 하죠.

형태는 다음과 같아요: `반환타입 함수이름(매개변수타입 매개변수이름);` (매개변수 이름은 생략 가능)

따라서 `inch2cm` 함수의 원형은 이렇게 쓸 수 있어요:

double inch2cm(int inch);

또는 매개변수 이름을 생략하고 이렇게 써도 돼요:

double inch2cm(int);

반환 타입이 `double`, 함수 이름이 `inch2cm`, 받는 인자(매개변수) 타입이 `int`라는 정보가 다 들어있죠?

팩토리얼 함수, 어디가 틀렸을까? (문제 4)

팩토리얼(Factorial)은 1부터 어떤 정수 n까지 모든 정수를 곱한 값을 말해요 (n!). 예를 들어 3! = 3 * 2 * 1 = 6이죠. 다음 코드는 재귀 호출(함수가 자기 자신을 부르는 것)을 이용해서 팩토리얼을 구하는 함수인데, 틀린 부분을 고쳐야 해요.

// 틀린 코드
void fac(int n) {
    if (n > 1) return 1; // 여기가 이상해요!
    return n*fac(n); // 여기도 이상해요!
}

// 고친 코드
int fac_corrected(int n) { // 반환 타입이 void가 아니라 int여야 해요. 팩토리얼 '값'을 반환해야 하니까요.
    if (n <= 1) { // 재귀 호출을 멈추는 조건 (Base case)
        return 1; // 0! 과 1! 은 1이에요.
    } else { // 재귀적으로 계산하는 부분 (Recursive step)
        return n * fac_corrected(n - 1); // n * (n-1)! 을 계산해요.
    }
}

어디가 틀렸었는지 볼까요?

  1. 반환 타입: 팩토리얼 '값'(정수)을 돌려줘야 하는데, 함수 반환 타입이 `void`(돌려주는 값 없음)로 되어 있었어요. `int`로 바꿔야 해요.
  2. 종료 조건 (Base Case): 재귀 함수는 언젠가 멈춰야 무한 반복에 빠지지 않아요. 팩토리얼은 n이 1 이하일 때 1이 되므로, `if (n <= 1)`일 때 `return 1;`을 해줘야 멈출 수 있어요. 원래 코드는 `if (n > 1) return 1;` 이라서 n이 1보다 클 때 1을 반환하고 끝나버리니 계산이 제대로 될 리가 없죠.
  3. 재귀 호출 부분 (Recursive Step): n!은 n * (n-1)! 과 같아요. 따라서 `n * fac(n - 1)`을 호출해야 하는데, 원래 코드는 `n * fac(n)`으로 자기 자신을 계속 같은 값으로 부르니 무한 반복에 빠지거나 잘못된 계산을 하게 돼요.

재귀 함수를 만들 때는 반드시 '종료 조건'과 '재귀 호출 부분'을 정확하게 정의해야 한다는 것을 기억하세요!

블랙홀 크기 계산하기! - 함수 활용 (문제 5)

주어진 `blackhole_size` 함수를 이용해서 지구 질량 블랙홀의 반경을 계산하는 문제예요. 지구 질량은 태양 질량의 약 33만분의 1이라고 하네요.

#include <stdio.h> // printf 함수를 사용하기 위해 필요해요

// 주어진 함수
double blackhole_size(double sunmass) {
    // 태양 질량(sunmass)을 기준으로 블랙홀 반경(mm) 계산
    return 1.48 * sunmass * 1000000.0; // 1.48 * 10^6 * sunmass 와 같아요
}

int main() {
    // 지구 질량을 태양 질량 단위로 표현
    double earth_mass_in_sun_units = 1.0 / 330000.0; // 33만분의 1

    // blackhole_size 함수를 호출하여 지구 질량 블랙홀의 반경 계산
    double radius_mm = blackhole_size(earth_mass_in_sun_units);

    // 결과 출력
    printf("지구 질량 블랙홀의 반경: 약 %.10f mm\n", radius_mm);
    // %.10f 는 소수점 아래 10자리까지 출력하라는 의미예요. 값이 매우 작을 테니까요.

    return 0;
}

먼저 지구 질량을 태양 질량 단위로 바꿔야 해요. 문제에서 33만분의 1이라고 했으니 `1.0 / 330000.0`으로 계산할 수 있어요. (정수 나누기가 되지 않도록 1.0처럼 소수점으로 써주는 게 좋아요!)

그 다음, 이 값을 `blackhole_size` 함수에 인자로 넣어서 호출하면, 함수가 알아서 계산된 반경 값(mm 단위)을 돌려줘요. 이 값을 `radius_mm` 변수에 저장하고 `printf` 함수로 출력하면 끝!

함수를 사용하면 복잡한 계산을 함수 안에 숨기고, 필요할 때 간단하게 이름만 불러서 사용할 수 있어서 코드가 훨씬 깔끔해지고 이해하기 쉬워진답니다.

C언어의 약속: 값에 의한 호출이란? (문제 6)

C 언어 함수는 인자를 전달할 때 '값에 의한 호출(call by value)' 방식을 사용해요. 이게 무슨 뜻일까요?

함수를 호출할 때 넘겨주는 값(인자)은, 그 값 자체가 넘어가는 것이 아니라 값이 복사되어서 함수의 매개변수(인자를 받는 변수)에 전달된다는 의미예요. 마치 복사본을 만들어서 주는 것과 같아요.

그래서 함수 안에서 매개변수의 값을 아무리 바꿔도, 함수를 호출한 곳에 있는 원래 변수의 값에는 아무런 영향을 주지 않아요. 복사본을 바꾼 것이지 원본을 바꾼 게 아니니까요!

(만약 함수 안에서 원본 변수의 값을 바꾸고 싶다면, 변수의 '주소'를 알려주는 포인터를 사용해야 해요.)

새로 배운 C언어 명령어는? (문제 7)

2학기에 프로그래밍을 배우면서 새로 알게 된 C언어 키워드(명령어)들을 적어보는 문제네요. 1학기 내용과 비교해서 어떤 것들이 있었을까요? (정확한 답은 수업 내용에 따라 다르겠지만, 일반적으로 2학기에는 이런 내용들을 배울 수 있어요)

  • 제어문 관련: `switch`, `case`, `default`, `continue`, `break` (for, while, if, else는 보통 1학기에 배우죠)
  • 함수 관련: `void`, `return` (함수 정의 및 호출 관련)
  • 자료형 관련: `double`, `float` (실수형), `char` (문자형), `short`, `long` (정수형 확장), `unsigned` (부호 없는 정수), `typedef` (자료형 이름 재정의), `enum` (열거형)
  • 저장 클래스 관련: `auto`, `static`, `extern`, `register` (변수의 저장 위치나 생존 기간 관련)
  • 포인터 관련: `*`, `&` (포인터 선언 및 주소 연산)
  • 구조체/공용체 관련: `struct`, `union`
  • 기타: `sizeof` (크기 계산 연산자)

이 중에서 2학기 수업 때 새로 배웠다고 생각되는 키워드들을 적으면 된답니다!

오늘 2018년도 중간고사 문제를 통해 C언어의 다양한 기본 개념들을 다시 한번 살펴봤어요. 꾸준히 복습하고 직접 코드를 짜보는 연습을 하는 것이 실력 향상의 가장 좋은 방법이랍니다. 힘내세요!

 

 

개념 설명 관련 코드/키워드
조건 연산자 vs if-else 같은 조건 분기 기능을 다른 방식으로 표현. `? :`, `if`, `else`
while문 vs for문 같은 반복 기능을 다른 구조로 표현. `for`는 초기식, 조건식, 증감식을 한 곳에 명시. `while`, `for`
함수 원형 (Prototype) 함수의 이름, 반환 타입, 매개변수 타입을 컴파일러에게 미리 알림. `반환타입 함수이름(매개변수타입);`
재귀 함수 (Recursion) 함수가 자기 자신을 호출하는 방식. 종료 조건(Base Case)이 필수. `if (종료조건) return ...; else return ... 함수호출(...);`
함수 활용 복잡한 작업을 함수로 만들어 재사용성 및 가독성 높임. 함수 정의, 함수 호출
값에 의한 호출 (Call by Value) 함수 호출 시 인자의 '값'이 복사되어 전달됨. 원본 변수 불변. C언어 기본 인자 전달 방식
C언어 키워드 C언어 문법을 구성하는 예약어. `switch`, `continue`, `break`, `void`, `return`, `double`, `char`, `static`, `struct` 등
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함