Структура "Историческое событие". Найти интервал между двумя событиями в днях - C (СИ)
Формулировка задачи:
Решение задачи: «Структура "Историческое событие". Найти интервал между двумя событиями в днях»
- #include <stdio.h>
- #include <malloc.h>
- #include <math.h>
- int mn[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- struct _event
- {
- int day;
- int month;
- int year;
- char* event;
- };
- struct event_node
- {
- struct _event* ev;
- struct event_node* next;
- };
- int is_leap_year(int year)
- {
- if (year%4 == 0)
- return 1;
- else
- return 0;
- }
- // ввод
- // аргумент функции нельзя передавать через одинарный указатель.
- void enter_event(struct event_node** c)
- {
- struct event_node* iterator;
- if (*c == 0)
- {
- *c = (struct event_node*) malloc( sizeof(struct event_node) );
- if (*c != 0)
- {
- (*c)->next = 0;
- (*c)->ev = 0;
- (*c)->ev = (struct _event*) malloc( sizeof(struct _event) );
- if ((*c)->ev != 0)
- {
- (*c)->ev->event = 0;
- (*c)->ev->day = 18;
- (*c)->ev->month = 3;
- (*c)->ev->year = 2015;
- (*c)->ev->event = (char*) malloc( 2 * sizeof(char) );
- if ((*c)->ev->event != 0)
- {
- (*c)->ev->event[0] = 't';
- (*c)->ev->event[1] = '\0';
- }
- }
- }
- }
- else
- {
- iterator = *c;
- while (iterator->next != 0)
- iterator = iterator ->next;
- iterator->next = (struct event_node*) malloc( sizeof(struct event_node) );
- if (iterator ->next != 0)
- {
- iterator->next->next = 0;
- iterator->next->ev = (struct _event*) malloc( sizeof(struct _event) );
- if (iterator ->next ->ev != 0)
- {
- iterator->next->ev->event = 0;
- iterator->next->ev->day = 18;
- iterator->next->ev->month = 3;
- iterator->next->ev->year = 2015;
- iterator->next->ev->event = (char*) malloc( 2 * sizeof(char) );
- if (iterator->next->ev->event != 0)
- {
- iterator->next->ev->event[0] = 't';
- iterator->next->ev->event[1] = '\0';
- }
- }
- }
- }
- }
- // вывод
- void print_event_internal(struct _event* c)
- {
- if (c == 0) return;
- printf("%d %d %d %s\n", c->day, c->month, c->year, c->event);
- }
- void print_event(struct event_node** c)
- {
- struct event_node* iterator = *c;
- if (iterator == 0) return;
- while (iterator->next != 0)
- {
- print_event_internal(iterator->ev);
- iterator = iterator ->next;
- }
- print_event_internal(iterator->ev);
- }
- // разность между датами (предполагается что год 1 события c больше года 2 события с1)
- // погрешность +-1
- int diff_event_internal(struct _event* c, struct _event* c1)
- {
- int day;
- int month;
- int year;
- int tday;
- int tmonth;
- int tyear;
- int r;
- if (c == 0) return -1;
- day = c1->day;
- month = c1->month;
- year = c1->year;
- if (year == c->year)
- {
- if (month == c->month) { return (abs(day - c->day)); }
- else
- {
- r = c->day;
- tmonth = c->month;
- tmonth--;
- while (tmonth != month && tmonth > 0)
- {
- r += mn[tmonth-1];
- if (tmonth-1 == 1&& is_leap_year(c->year) ) r += 1;
- tmonth--;
- }
- tday = mn[tmonth-1];
- if (tmonth-1 == 1 && is_leap_year(c->year)) tday += 1;
- r += abs(tday - day);
- return r;
- }
- }
- else
- {
- //
- r = c->day;
- tmonth = c->month;
- tmonth--;
- while ( tmonth > 0 )
- {
- r += mn[tmonth-1];
- tmonth--;
- }
- tyear = c->year;
- tyear--;
- while(tyear != year && tyear > 0)
- {
- r += 364;
- if ( is_leap_year(tyear) == 1) r += 1;
- tyear--;
- }
- //
- tmonth = 12;
- while (tmonth != month && tmonth > 0)
- {
- r += mn[tmonth-1];
- if (tmonth-1 == 1 && is_leap_year(c->year) ) r += 1;
- tmonth--;
- }
- tday = mn[tmonth-1];
- if (tmonth-1 == 1 && is_leap_year(c->year)) tday += 1;
- r += abs(tday - day);
- return r;
- //
- }
- return (-1);
- }
- int diff_event(struct event_node** c)
- {
- struct event_node* iterator = *c;
- // событие, с которым происходит сравнение
- struct _event c1;
- c1.day = 18;
- c1.month = 1;
- c1.year = 2013;
- if (iterator == 0) return;
- while (iterator->next != 0)
- {
- printf("%d\n", diff_event_internal(iterator->ev, &c1));
- iterator = iterator ->next;
- }
- printf("%d\n", diff_event_internal(iterator->ev, &c1));
- return 0;
- }
- // сборка мусора неавтоматическая (garbage collection unautomatic)
- void free_event(struct event_node** c)
- {
- struct event_node* f;
- struct event_node* iterator = *c;
- if (iterator == 0) return;
- while (iterator->next != 0)
- {
- f = iterator;
- iterator = iterator ->next;
- if (f->ev->event != 0) free(f->ev->event); f->ev->event = 0;
- if (f->ev != 0) free(f->ev); f->ev = 0;
- if (f != 0) free(f); f = 0;
- }
- if (iterator != 0) free(iterator); iterator = 0;
- }
- int main(int argc, char* argv[])
- {
- struct event_node* first;
- first = 0;
- enter_event(&first);
- enter_event(&first);
- enter_event(&first);
- print_event(&first);
- diff_event(&first);
- free_event(&first);
- return 0;
- }
Объяснение кода листинга программы
Структура Историческое событие
реализуется в виде массива структур _event. В данном случае, массив имеет размер 12, что соответствует количеству месяцев в году. Каждый элемент массива содержит информацию о дне, месяце и годе события, а также строку с описанием события.
Для работы с этими структурами создается структура event_node, которая содержит указатель на следующую структуру event_node (для связывания структур в список) и указатель на структуру _event.
Функция is_leap_year() используется для определения, является ли год високосным.
Функция enter_event() добавляет новое событие в начало списка. Если список пуст, то создается новый узел списка. В противном случае, новый узел списка добавляется в начало списка.
Функция print_event() выводит все события из списка на экран.
Функция diff_event() вычисляет разницу между двумя событиями в днях. Если год события c1 больше года события c, то разница вычисляется в днях. Если год события c1 меньше года события c, то разница вычисляется в днях, при этом год c1 уменьшается до года c.
Функция free_event() освобождает память, занятую узлами списка и структурами _event.
В функции main() создается первый узел списка, затем добавляются еще два события, после чего список выводится на экран и вычисляется разница между первым и последним событиями. Затем память, занятая узлами списка и структурами _event, освобождается.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д