글
[DigitalClock 클래스의 Class Diagram]
앞에서, Util.h 와 Util.c 파일에 대해서 설명드렸으니, 이번 시간에는, DigitalClock.h 와 DigitalClock.c 를 분석해 보겠습니다.
[DigitalClock.h]
#ifndef _DIGITAL_CLOCK_H #define _DIGITAL_CLOCK_H // ex) 12:24:36 enum{ HOUR_LEFT, // left digit of hour HOUR_RIGHT, // right digit of hour DELIMITER_BETWEEN_HOUR_AND_MINUTE, // colon between hour and minute MINUTE_LEFT, // left digit of minute MINUTE_RIGHT, // right digit of minute DELIMITER_BETWEEN_MINUTE_AND_SECOND, // colon between minute and second SECOND_LEFT, // left digit of second SECOND_RIGHT // right digit of second }; typedef struct _digitalClock{ int year; int month; int dayOfMonth; int dayOfWeek; // Sunday (0), Monday (1), ... int hour; int minute; int second; }DigitalClock; #define ONE_SECOND 1000 #define INITIAL_X_POSITION_FOR_TIME 2 #define INITIAL_Y_POSITION_FOR_TIME 3 #define Y_OFFSET_FOR_TIME 8 #define INITIAL_X_POSITION_FOR_DATE 22 #define INITIAL_Y_POSITION_FOR_DATE 1 #define TRUE 1 #define FALSE 0 DigitalClock DigitalClock_GetTime(); void DigitalClock_Print(DigitalClock digitalClock); #endif
1, 2, 39 라인
헤더파일 중복 삽입을 방지하기 위한 전처리기문입니다.
5 ~ 14 라인
시간을 출력하기 위해서, 시의 왼쪽 부분 (십의 자리), 시의 오른쪽 부분 (일의 자리), 시와 분 사이의 콜론, 분의 왼쪽 부분 (십의 자리), 분의 오른쪽 부분 (일의 자리), 분과 초 사이의 콜론, 초의 왼쪽 부분 (십의 자리), 초의 오른쪽 부분 (일의 자리) 의 순서를 정하고, 이 순서를 바탕으로 순서대로 일정 간격씩 커서를 이동하여 화면에 출력을 합니다.
16 ~ 24 라인
DigitalClock 이라는 구조체를 정의하는데, 멤버변수로 년도, 월, 일, 요일, 시, 분, 초를 갖고 있습니다. 단, 요일정보는 정수값으로, 일요일은 0 부터 시작합니다.
26 라인
Sleep 함수에서 향후 사용될 1 초를 나타내는 상수를 정의합니다.
27 ~ 28 라인
시간 출력시 사용될 시작 좌표의 위치 x, y 를 나타내는 상수를 정의합니다.
29 라인
시간 출력시 사용될 각 디지털 간의 간격을 상수로 정의합니다.
30 ~ 31 라인
날짜 출력시 사용될 시작 좌표의 위치 x, y 를 나타내는 상수를 정의합니다.
33 ~ 34 라인
참 (1), 거짓 (0) 을 나타내는 상수를 정의합니다.
36 ~ 37 라인
DigitalClock 과 관련된 함수들의 선언부입니다.
[DigitalClock.c]
#include <stdio.h> #include <time.h> #include <windows.h> #include "DigitalClock.h" #include "Util.h" #define DAY_OF_WEEK_SIZE 7 const static char* DAY_OF_WEEK[DAY_OF_WEEK_SIZE] = { " Sun ", " Mon ", " Tue ", " Wed ", " Thu ", " Fri ", " Sat " }; #define PATTERNS_TO_PRINT_LENGTH 11 #define PATTERNS_TO_PRINT_ROW 5 #define PATTERNS_TO_PRINT_COL 3 const static char patternsToPrint[PATTERNS_TO_PRINT_LENGTH][PATTERNS_TO_PRINT_ROW][PATTERNS_TO_PRINT_COL] = { { // 0 { 1, 1, 1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 } }, { // 1 { 0, 1, 0 }, { 0, 1, 0 }, { 0, 1, 0 }, { 0, 1, 0 }, { 0, 1, 0 } }, { // 2 { 1, 1, 1 }, { 0, 0, 1 }, { 1, 1, 1 }, { 1, 0, 0 }, { 1, 1, 1 } }, { // 3 { 1, 1, 1 }, { 0, 0, 1 }, { 1, 1, 1 }, { 0, 0, 1 }, { 1, 1, 1 } }, { // 4 { 1, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 0, 1 }, { 0, 0, 1 } }, { // 5 { 1, 1, 1 }, { 1, 0, 0 }, { 1, 1, 1 }, { 0, 0, 1 }, { 1, 1, 1 } }, { // 6 { 1, 0, 0 }, { 1, 0, 0 }, { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 } }, { // 7 { 1, 1, 1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 } }, { // 8 { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 } }, { // 9 { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 0, 1 }, { 0, 0, 1 } }, { // : { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } } }; static void _DigitalClock_PrintDate(DigitalClock digitalClock); static void _DigitalClock_PrintTime(DigitalClock digitalClock); static void _PrintPattern(int pattern, int type); DigitalClock DigitalClock_GetTime(){ DigitalClock digitalClock = {0, }; time_t now = time(NULL); struct tm* time = localtime(&now); digitalClock.year = time->tm_year + 1900; digitalClock.month = time->tm_mon + 1; digitalClock.dayOfMonth = time->tm_mday; digitalClock.dayOfWeek = time->tm_wday; digitalClock.hour = time->tm_hour; digitalClock.minute = time->tm_min; digitalClock.second = time->tm_sec; return digitalClock; } void DigitalClock_Print(DigitalClock digitalClock){ _DigitalClock_PrintDate(digitalClock); _DigitalClock_PrintTime(digitalClock); Sleep(ONE_SECOND - 20); } static void _DigitalClock_PrintDate(DigitalClock digitalClock){ CursorUtil_GotoXY(INITIAL_X_POSITION_FOR_DATE, INITIAL_Y_POSITION_FOR_DATE); printf("%d. %d. %d (%s)\n", digitalClock.year, digitalClock.month, digitalClock.dayOfMonth, DAY_OF_WEEK[digitalClock.dayOfWeek]); } static void _DigitalClock_PrintTime(DigitalClock digitalClock){ _PrintPattern(digitalClock.hour / 10, HOUR_LEFT); _PrintPattern(digitalClock.hour % 10, HOUR_RIGHT); _PrintPattern(':', DELIMITER_BETWEEN_HOUR_AND_MINUTE); _PrintPattern(digitalClock.minute / 10, MINUTE_LEFT); _PrintPattern(digitalClock.minute % 10, MINUTE_RIGHT); _PrintPattern(':', DELIMITER_BETWEEN_MINUTE_AND_SECOND); _PrintPattern(digitalClock.second / 10, SECOND_LEFT); _PrintPattern(digitalClock.second % 10, SECOND_RIGHT); } static void _PrintPattern(int pattern, int type){ int i = 0; int j = 0; int x = INITIAL_X_POSITION_FOR_TIME; int y = INITIAL_Y_POSITION_FOR_TIME; for (i = 0; i < type; i++){ x += Y_OFFSET_FOR_TIME; } if (!(pattern >= 0 && pattern <= 9)){ pattern = PATTERNS_TO_PRINT_LENGTH - 1; } CursorUtil_GotoXY(x, y++); for (i = 0; i < PATTERNS_TO_PRINT_ROW; i++){ for (j = 0; j < PATTERNS_TO_PRINT_COL; j++){ if (patternsToPrint[pattern][i][j]){ printf("■"); } else{ printf(" "); } } CursorUtil_GotoXY(x, y++); } CursorUtil_GotoXY(0, y); }
1 ~ 5 라인
DigitalClock.c 파일에서 필요한 함수나 변수를 위한 헤더파일 include 문입니다.
7 ~ 11 라인
요일을 문자열 상수 배열로 저장하여 전역 변수로 가지고 있습니다. const 를 사용한 이유는 상수화 하기 위함이고, static 을 붙인 이유는 현재 파일 내에서만 사용될 것이기 때문입니다.
13 ~ 95 라인
시간 출력시 사용될 디지털 패턴을 저장한 2 차원 배열입니다. 0 부터 9 까지의 숫자, 그리고 콜론을 나타내기 위해서 1 과 0 을 이용하여 표현하였습니다.
97 ~ 100 라인
DigitalClock.c 파일 내에서만 사용되는 내부 함수들의 선언부입니다.
102 라인
DigitalClock_GetTime 함수의 정의부입니다. 현재 시각을 가져와서 반환하는 역할을 합니다.
103 ~ 113 라인
현재 시각을 가져와서 DigitalClock 에 저장하고 이를 반환합니다.
(현재 시각 가져와서 출력하기 참고)
http://kkikkodev.tistory.com/25
116 라인
DigitalClock_Print 함수의 정의부입니다. 매개변수로 digitalClock 을 받아서 화면에 출력합니다.
117 라인
digitalClock 을 매개변수로 넘기면서 _DigitalClock_PrintDate 함수를 호출합니다.
118 라인
digitalClock 을 매개변수로 넘기면서 _DigitalClock_PrintTime 함수를 호출합니다.
119 라인
117, 118 라인에서 날짜, 시각을 출력했으니, 다음 1 초가 될 때까지 멈춥니다. 하지만, 정확히 1 초를 멈추게 되면 시간을 가져와서 가공해서 출력하는 처리시간이 걸리기 때문에, 엄밀히 따지면 이는 1 초를 넘기게 됩니다. 따라서 이러한 처리 시간이 누적되어 쌓여서, 초를 다시 가져왔을 때, 1 초가 아닌, 한 번에 2 초가 지나가버리는 경우가 발생하여, 실제로는 1 초보다 조금 작은 0.98 초를 Sleep 함수의 매개변수로 넘겨줍니다.
122 라인
_DigitalClock_PrintDate 함수의 정의부입니다. 매개변수로 digitalClock 을 받아서 날짜 부분만 화면에 출력합니다.
123 라인
날짜를 출력하기 위해서, 날짜 출력용 시작 위치로 커서를 이동시킵니다.
124 ~ 125 라인
digitalClock 의 멤버변수들을 이용해서 날짜 및 요일을 출력합니다.
129 라인
_PrintPattern 함수를 호출하면서, digitalClock 의 시의 왼쪽 부분의 값과 그 타입 (HOUR_LEFT) 를 넘겨줍니다.
130 라인
_PrintPattern 함수를 호출하면서, digitalClock 의 시의 오른쪽 부분의 값과 그 타입 (HOUR_RIGHT) 를 넘겨줍니다.
131 라인
_PrintPattern 함수를 호출하면서, 시와 분 사이에서 시와 분을 구분해 주기 위한 콜론 (:) 문자와 그 타입 (DELIMITER_BETWEEN_HOUR_AND_MINUTE) 를 넘겨줍니다.
132 라인
_PrintPattern 함수를 호출하면서, digitalClock 의 분의 왼쪽 부분의 값과 그 타입 (MINUTE_LEFT) 를 넘겨줍니다.
133 라인
_PrintPattern 함수를 호출하면서, digitalClock 의 분의 오른쪽 부분의 값과 그 타입 (MINUTE_RIGHT) 를 넘겨줍니다.
134 라인
_PrintPattern 함수를 호출하면서, 분과 초 사이에서 분과 초를 구분해 주기 위한 콜론 (:) 문자와 그 타입 (DELIMITER_BETWEEN_MINUTE_AND_SECOND) 를 넘겨줍니다.
135 라인
_PrintPattern 함수를 호출하면서, digitalClock 의 시의 왼쪽 부분의 값과 그 타입 (SECOND_LEFT) 를 넘겨줍니다.
136 라인
_PrintPattern 함수를 호출하면서, digitalClock 의 시의 오른쪽 부분의 값과 그 타입 (SECOND_RIGHT) 를 넘겨줍니다.
139 라인
_PrintPatter 함수의 정의부입니다. 매개변수로 pattern (출력될 모양의 패턴) 과 type (출력 위치를 구하기 위한 offset 을 계산하기 위한 변수) 를 받아서, 실제 디지털 패턴을 출력합니다.
142 ~ 146 라인
매개변수로 받은 타입에 따라서 출력될 좌표 위치를 결정합니다. 타입의 정수값이 클 수록 오른쪽에 출력됩니다.
147 ~ 149 라인
만약 매개변수로 받은 패턴이 콜론인 경우 (숫자가 아닌 경우), 패턴에는 10 을 저장합니다. 이는 미리 출력 패턴들이 0 과 1 로 저장되어 있는 patternToPrint 배열에서 콜론에 해당되는 패턴을 가져오기 위함입니다. (0 부터 9 까지는 숫자 패턴이 저장되어 있고, 10 번째는 콜론 패턴이 저장되어 있습니다.)
150 라인
142 ~ 146 라인에서 구한 패턴에 해당하는 출력 시작 위치로 커서를 이동시킵니다.
151 ~ 162 라인
patternToPrint 2 차원 배열에서 해당되는 패턴 위치 (숫자 or 콜론) 의 값이 0 이면 빈 칸을, 1 이면 ■ 를 출력하고, 다음 줄로 이동하면서 계속 패턴을 출력합니다.
'1.2) 프로젝트 > 디지털 시계' 카테고리의 다른 글
디지털 시계 ver 0.2 (1) - 실행 결과 & 프로젝트 개요 (0) | 2015.07.18 |
---|---|
디지털 시계 ver 0.1 (6) - 개발 완료 / 후기 (4) | 2015.04.11 |
디지털 시계 ver 0.1 (5) - 소스코드 구현 (Main) (0) | 2015.04.11 |
디지털 시계 ver 0.1 (3) - 소스코드 구현 (Util) (0) | 2015.04.10 |
디지털 시계 ver 0.1 (2) - 프로그램 설계 (Use Case, Class, Sequence) (0) | 2015.04.10 |
디지털 시계 ver 0.1 (1) - 실행 결과 & 프로젝트 개요 (2) | 2015.04.10 |
RECENT COMMENT