2015-04-18 2 views
1

У меня проблема с этим кодом, я не понимаю, как работает эта функция. Мне нужно проверить вход пользователя, чтобы проверить, действительна ли дата их размещения. И если это не я устанавливаю код ошибки. Таким образом, в моей функции чтения I cin дата затем проверяет ввод и вызывает mdays(), однако по какой-то причине я не знаю, как проверить в инструкции if if функцию чтения, если дата подтверждена или нет.Объясните этот високосный год Функция C++

int Date::mdays() const 
{ 
    int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, -1}; 
    int mon = _mon >= 1 && _mon <= 12 ? _mon : 13; 
    mon--; 
    return days[mon] + int((mon == 1)*((_year % 4 == 0) && 
     (_year % 100 != 0)) || (_year % 400 == 0)); 
} 
+1

У вас есть базовое число дней в массиве. Есть один специальный случай, когда вам нужно добавить его, и это февраль в високосный год. Второй операнд '+' оценивается в 1 в этом случае и 0 в противном случае. – chris

+0

Одна вещь, неверная в этой функции, заключается в том, что она делает слишком много вещей: диапазон проверяет месяцы, вычисляет високосный год, вычисляет последний день месяца. См. Http://howardhinnant.github.io/date_algorithms.html#last_day_of_month для простых, эффективных и компактных алгоритмов даты. –

ответ

0

Вы можете изменить подпись mdays() возвращает логическое значение, чтобы указать, если дата проверки или нет, и положить выходной аргумент для сохранения дней, если дата проверки

bool Date::mdays(int& month_days) const { 
    int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 
    if (_mon < 1 || _mon > 12) return false; 
    mon--; 
    month_days = days[mon] + int((mon == 1)*((_year % 4 == 0) && (_year % 100 != 0)) || (_year % 400 == 0)); 
    return true; 
} 
2

Код очень умный, написанный кем-то, кто хотел продемонстрировать, что они умны. Я ненавижу умный код. (Это тоже довольно медленно, я ненавижу код, который пытается быть умным и терпит неудачу).

Помните правила leapyears:

Каждый четвертый год является високосным. За исключением того, что каждый 100-й год не является високосным годом. За исключением того, что каждый 400-й год является високосным годом.

В большинстве месяцев вы можете посмотреть из таблицы, за исключением того, что февраль имеет 28 или 29 дней. Итак, чтобы понять код, что произойдет, если месяц не в феврале? А что будет, если месяц февраль? mon будет равно 1. Какова ценность (mon == 1) в феврале? Как бы вы выразили правила для високосных лет?

И функция, которую вы показали , вычисляет количество дней в месяце, это не делает никакой проверки. Очевидно, вам нужно знать, что в апреле 30 дней известно, что 31 апреля недействительно.

0

Если вы можете изменить Date класс, вы должны быть в состоянии создать новый метод, использующий возвращаемое значение mdays(), как это:

bool Date::validate_day_and_month() const { 
    int maxday = mdays(); 
    if (maxday < 0) { return false; } // mdays() = -1 if _month is bad 
    if (_day <= 0 || _day > maxday) { return false; } 
    return true; 
} 

Здесь _day это день часть ввода даты пользователя.