현재 레벨에서는 이 정도로만 하고, 다음 레벨에 가서 포인터 타입을 사용하는 방법을 소개한다. 참고로 대입 연산자 =의 동작은 모든 구조체 타입에 대해 명확히 정의됐지만 비교 연산자(==, !=)는 그렇지 않다.
TAKEAWAY 6.26 구조체는 =로 대입할 수 있지만 ==나 !=로 비교할 수는 없다.
예제 6-3은 struct tm을 활용하는 예 전체를 보여 준다. 여기서는 표준 헤더인 time.h를 사용하기 때문에 struct tm을 선언하는 예전 방식은 나오지 않는다. 요즘은 개별 멤버의 타입을 서로 다르게 지정할 때가 많지만, C 언어는 오래 전에 결정했던 방식을 그대로 유지하는 경우가 많다.
예제 6-3 struct tm을 다루는 예제
1 #include <time.h>
2 #include <stdbool.h>
3 #include <stdio.h>
4
5 bool leapyear(unsigned year) {
6 /* 세기 첫 해가 아니고
7 400으로 나눠떨어지지 않는 해 중에서
8 4로 나눠떨어지는 해는 모두 윤년이다. */
9 return !(year % 4) && ((year % 100) || !(year % 400));
10 }
11
12 #define DAYS_BEFORE \
13 (int const[12]){ \
14 [0] = 0, [1] = 31, [2] = 59, [3] = 90, \
15 [4] = 120, [5] = 151, [6] = 181, [7] = 212, \
16 [8] = 243, [9] = 273, [10] = 304, [11] = 334, \
17 }
18
19 struct tm time_set_yday(struct tm t) {
20 // tm_mdays starts at 1.
21 t.tm_yday += DAYS_BEFORE[t.tm_mon] + t.tm_mday - 1;
22 // Takes care of leap years
23 if ((t.tm_mon > 1) && leapyear(t.tm_year+1900))
24 ++t.tm_yday;
25 return t;
26 }
27
28 int main(void) {
29 struct tm today = {
30 .tm_year = 2019-1900,
31 .tm_mon = 4-1,
32 .tm_mday = 3,
33 .tm_hour = 10,
34 .tm_min = 0,
35 .tm_sec = 47,
36 };
37 printf("this year is %d, next year will be %d\n",
38 today.tm_year+1900, today.tm_year+1900+1);
39 today = time_set_yday(today);
40 printf("day of the year is %d\n", today.tm_yday);
41 }