Skip to content

Instantly share code, notes, and snippets.

@sftblw
Last active October 20, 2016 14:44
Show Gist options
  • Save sftblw/a33ac29ce51183a181a6e4783c9872e1 to your computer and use it in GitHub Desktop.
Save sftblw/a33ac29ce51183a181a6e4783c9872e1 to your computer and use it in GitHub Desktop.
2016_10_21_컴퓨터공학실험_문제_sftblw.md

직접 만든 문제입니다. 이 중에 두 문제를 선택했는데 심지어 더 쉽게 수정까지 했는데 빠꾸먹었다고... ...전달받아서 원본을 공개합니다.

답안도 같이 나와있으니 문서를 읽을 시 주의바랍니다.

컴퓨터공학과 1학년을 대상으로 한 문제입니다.

범위는

  1. 리눅스에서 gcc 사용, C언어 (C99를 가르치기엔 복잡해지니 ANSI C 기준)
  2. 함수의 정의 및 사용
  3. 파일을 여러개로 분리하여 컴파일

정도입니다.

CC-BY-SA, by sftblw

문제 1

스토리 게임을 만드려고 한다. 문장을 출력한 뒤, 문장 끝 부분에 연필이 굴러가는 것 같은 애니메이션을 넣으면 좋을 것 같다.

\busleep(int)을 사용하여 회전하는 기호 (\, |, /, - 를 순서대로 출력) 가 지정한 횟수만큼 반복하여 출력되는 함수 marked_sleep(int repeat_count)를 작성하고 출력하는 데 사용하라. usleep(int)으로 각각의 기호를 출력할 때마다 0.25 초씩 대기하라.

  • \b 기호를 사용하면 한 글자 앞으로 커서를 옮길 수 있다. 실제로 지워지지는 않지만, 지운다고 생각하면 편하다. \b 기호를 출력한 뒤에 화면에 결과가 나오지 않는다면 printf("\b")를 호출한 후 fflush(stdio)를 호출하라.
  • usleep(int)unistd.h 헤더에 있으며, 마이크로초를 입력으로 받아 대기하므로, 실제 호출할 때는 초단위로 대기하려면 1000 * 1000 을 곱해야 한다.
#include <stdio.h>
#include <unistd.h>

void marked_sleep(int repeat_count);

int main() {
  // 예제 입력
  printf("It is a good day to die... ");
  marked_sleep(3);
  printf("\n");
  printf("and do a barrel roll... ");
  marked_sleep(4);
  printf("\n");
  printf("and HEROES OF THE STORM! ");
  marked_sleep(5);
  printf("\n");
}

모범답안

#include <stdio.h>
#include <unistd.h>

void marked_sleep(int repeat_count);

int main() {
  // 예제 입력
  printf("It is a good day to die... ");
  marked_sleep(3);
  printf("\n");
  printf("and do a barrel roll... ");
  marked_sleep(4);
  printf("\n");
  printf("and HEROES OF THE STORM! ");
  marked_sleep(5);
  printf("\n");
}

void marked_sleep(int repeat_count) {
  int delay = 1000 * 1000 / 4;
  int i = 0;
  printf(" ");
  for (i = 0; i < repeat_count; i++) {
    printf("\b\\");
    fflush(stdout);
    usleep(delay);

    printf("\b|");
    fflush(stdout);
    usleep(delay);

    printf("\b/");
    fflush(stdout);
    usleep(delay);

    printf("\b-");
    fflush(stdout);
    usleep(delay);
  }
  printf("\b ");
  fflush(stdout);
}

문제 2

그림을 그리는 함수를 만들어놓고 나중에 쓰려고 한다.

속이 빈 사각형을 출력하는 함수 draw_rect(int width, int height) 와 속이 찬 사각형을 출력하는 함수 fill_rect(int width, int height) 를 별도의 파일 paint_rect.cpaint_rect.h 에 작성하여 컴파일하고 메인 함수에서 출력하는 프로그램을 작성하라.

  • 속이 빈 사각형을 출력할 때, 가로폭 1, 세로폭 1인 경우에도 정상적으로 출력할 수 있어야 한다.
    • 힌트: *는 출력할 수 있는 조건에만 출력하고, 그 외에는 모두 공백을 출력하면 됨
  • #ifndef 등을 사용하여 헤더 paint_rect.h 가 여러 번 include 되어도 동작할 수 있게 작성하고 이를 보여라.
  • 참고: 그리는 함수에서 사용하는 for문은 i, j 같은 변수명보다 x, y 같은 변수명을 사용하는 게 덜 헷갈린다.
draw rect: 5 3
*****
*   *
*****

fill rect: 5 3
*****
*****
*****

모범답안

  • main.c
#include <stdio.h>
#include "paint_rect.h"
#include "paint_rect.h"

int main() {
  int width, height;
  printf("draw rect: ");
  scanf(" %d %d", &width, &height);
  draw_rect(width, height);
}
  • paint_rect.h
#ifndef __DRAW_RECT_H__
#define __DRAW_RECT_H__

void draw_rect(int width, int height);
void fill_rect(int width, int height);

#endif
  • paint_rect.c
#include "paint_rect.h"

void draw_rect(int width, int height) {
  int y, x;
  for (y = 0; y < height; y++) {
    for (x = 0; x < width; x++) {
      if (x == 0
        || x == width - 1
        || y == 0
        || y == height - 1
      ) {
        printf("*");
      }
      else printf(" ");
    }
    printf("\n");
  }
}
void fill_rect(int width, int height) {
  int y, x;
  for (y = 0; y < height; y++) {
    for (x = 0; x < width; x++) {
      printf("*");
    }
    printf("\n");
  }
}

문제 3

모바일 게임 <신데렐라 대전쟁> 에는 스태미너라는 자원이 있다. "스태미너"를 사용해야 게임을 플레이할 수 있고, "스태미너"가 5분마다 1씩 자동으로 충전된다.

  • 현재 스태미너와 최대 스태미너를 입력받아 스태미너가 완전히 충전되려면 몇 분 걸리는지 반환하는 함수 stamina_calculate(int current_stamina, int max_stamina)를 별도의 파일 stamina.hstamina.c에 작성하라.
  • 분을 입력받아 "7hour 2min", "3day 4hour 6min"과 같은 형태로 출력하는 함수 print_duration(int minute)를 위에서 만든 파일에 작성하라. 출력 형식은 일, 시, 분 외에는 고려하지 않는다.
  • 위 두 함수를 사용하여, 현재 스태미너와 최대 스태미너를 입력받으면 stamina_calculate_print(int current_stamina, int max_stamina)몇 시간 걸리는지 출력하는 함수를 위에서 만든 파일에 작성하고 main 함수에서 테스트하라.
  • #ifndef 등을 사용하여 헤더 paint_rect.h 가 여러 번 include 되어도 동작할 수 있게 작성하고 이를 보여라.
current stamina: 346
max     stamina: 765
charge duration: 1day 10hour 55min

모범답안

  • main.c
#include <stdio.h>
#include "stamina.h"

int main() {
  int current_stamina, max_stamina;

  printf("current stamina: ");
  scanf(" %d", &current_stamina);
  printf("max     stamina: ");
  scanf(" %d", &max_stamina);
  printf("charge duration: ");
  stamina_calculate_print(current_stamina, max_stamina);
}
  • stamina.h
#ifndef __STAMINA_H__
#define __STAMINA_H__

int stamina_calculate(int current_stamina, int max_stamina);
void print_duration(int minute);
void stamina_calculate_print(int current_stamina, int max_stamina);

#endif
  • stamina.c
#include "stamina.h"

int stamina_calculate(int current_stamina, int max_stamina) {
  return (max_stamina - current_stamina) * 5;
}
void print_duration(int minute) {
  int day, hour;
  if (minute > 60 * 60) {
    day = minute / (60 * 60);
    minute %= (60 * 60);
    printf("%dday ", day);
  }
  if (hour > 60) {
    hour = minute / (60);
    minute %= (60);
    printf("%dhour ", hour);
  }
  printf("%dmin\n", minute);
}
void stamina_calculate_print(int current_stamina, int max_stamina) {
  print_duration(stamina_calculate(current_stamina, max_stamina));
}

문제 사이사이에 끼어있는 이상한 내용들 해설

여담

  • 2번 문제는 1학기때 조교로 들어갔다 낸 문제인데, x나 y중 하나가 1이거나 2인 경우에 대해 못 하는 경우가 많았습니다.
  • 3번 문제도 마찬가지로 1학기때 조교로 들어갔다 냈던 것을 약화한 문제입니다. 좀 더 복잡하게 만드려면, 실제로 언제 다 충전되는지 계산하라고 하면 더 어렵게 만들 수 있습
  • 1번은 재밌으라고 낸 건데 실습용으로는 적절치 않다는 지적이 많이 들어왔습니다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment