Избавиться от условных конструкций в C
Есть программа, которая принимает на вход дату рождения, а также текущую дату. Задание - определить следующие вещи:
- Родился ли человек в високосный год
- В год какого животного родился человек
- Какой знак зодиака у человека
- Сколько дней прожил человек с рождения
Мой код выглядит таким образом:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
int main()
{
time_t timeA, timeB;
struct tm tA, tB, *tptr;
int difference;
int year, month, date, currentYear, currentMonth, currentDate, yearNumber;
char *lapYear;
char *astroSign;
const char *yearAnimals[12] = {"Pig", "Dog", "Rooster", "Monkey", "Sheep", "Horse", "Snake", "Dragon", "Rabbit", "Tiger", "Buffalo", "Rat"};
printf("Enter your year, month and day of birth with space: "); scanf("%d%d%d", &year, &month, &date);
printf("Enter the current date with space: "); scanf("%d%d%d", ¤tYear, ¤tMonth, ¤tDate);
yearNumber = abs((year - 2019) % 12);
if (year % 4 == 0) {
lapYear = "Yes";
} else {
lapYear = "No";
}
time(&timeA);
time(&timeB);
tptr = localtime(&timeA);
tA = *tptr;
tptr = localtime(&timeB);
tB = *tptr;
// today
tA.tm_mday = currentDate;
tA.tm_mon = currentMonth;
tA.tm_year = currentYear;
// birth date
tB.tm_mday = date;
tB.tm_mon = month;
tB.tm_year = year;
timeA = mktime(&tA);
timeB = mktime(&tB);
difference = (int)(difftime(timeA, timeB) / 86400);
if ((month == 1 && date < 20) || (month == 12 && date >= 22)) {
astroSign = "Capricorn";
}
else if ((month == 2 && date < 19)){
astroSign = "Aquarius";
}
else if((month == 3 && date < 21) || (month == 2 && date >= 19)) {
astroSign = "Pisces";
}
else if ((month == 4 && date < 20) || (month == 3 && date >= 21)) {
astroSign = "Aries";
}
else if ((month == 5 && date < 21) || (month == 4 && date >= 20)) {
astroSign = "Taurus";
}
else if ((month == 6 && date < 21) || (month == 5 && date >= 21)) {
astroSign = "Gemini";
}
else if ((month == 7 && date < 23) || (month == 6 && date >= 21)) {
astroSign = "Cancer";
}
else if ((month == 8 && date < 23) || (month == 7 && date >= 23)) {
astroSign = "Leo";
}
else if ((month == 9 && date < 23) || (month == 8 && date >= 23)) {
astroSign = "Virgo";
}
else if ((month == 10 && date < 23) || (month == 9 && date >= 23)) {
astroSign = "Libra";
}
else if ((month == 11 && date < 22) || (month == 10 && date >= 23)) {
astroSign = "Scorpio";
}
else if ((month == 12 && date < 22) || (month == 11 && date >= 22)) {
astroSign = "Sagittarius";
}
printf("You were born in a lap year: %s \n", lapYear);
printf("Animal of your year: %s \n", yearAnimals[yearNumber]);
printf ("You are %d days old\n", difference);
printf ("Your astro sign is %s\n", astroSign);
}
Код работает без каких-либо ошибок, но есть несколько вопросов:
- Количество прожитых дней считается через библиотеку <time.h>. Как можно посчитать количество прожитых дней без нее, если надо учитывать, что года бывают високосные, а в месяцах разное количество дней?
- Можно ли определить знак зодиака не через множество if...else, а через какую-то более гибкую конструкцию?
Ответы (1 шт):
Автор решения: Алексей Р
→ Ссылка
- Разница между датами в днях
- См. вариант решения ниже (полностью не тестировал) + Определение знака зодиака по дате + Case20. Решебник Абрамяна М. Э.
#include <stdio.h>
int main ()
{
int dates[] = { 0, 19, 18, 20, 19, 20, 21, 22, 22, 22, 22, 22, 21 };
const char *names[] = { "Capricorn", "Aquarius", "Pisces", "Aries", "Taurus", "Gemini",
"Cancer", "Leo", "Virgo", "Libra", "Scorpio", "Sagittarius", "Capricorn"};
int m = 9;
int d = 24;
printf ("Your astro sign is %s\n", names[(d > dates[m]) ? m : m-1]);
return 0;
}
Your astro sign is Libra