структурировать время; против времени tm = {}. Тот же результат, но не то же самое?

Я задавал некоторые вопросы по программированию на этом веб-сайте под названием Kattis. Вот ссылка на вопрос, который я задавал: https://open.kattis.com/problems/datum

Пока я пытался решить эту проблему, я обнаружил кое-что очень, очень, очень странное.

Прежде чем я начну, вот два кода:

Первый:

#include <iostream>
#include <ctime>
#include <string>

using namespace std;

int main()
{
    //a = day, b = month
    string days[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

    struct tm time;

    cin >> time.tm_mday >> time.tm_mon;

    time.tm_year = 2009-1900;
    time.tm_mon--;

    mktime(&time);

    cout << days[time.tm_wday] << endl;

    return 0;
}

Второй:

#include <iostream>
#include <ctime>
#include <string>

using namespace std;

int main() {
    //a = day, b = month
    string days[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

    tm time = {};

    cin >> time.tm_mday >> time.tm_mon;

    time.tm_year = 2009-1900;
    time.tm_mon--;

    mktime(&time);

    cout << days[time.tm_wday] << endl;

    return 0;
}

Это ТОЧНЫЙ ОДИНАКОВЫЙ код, за исключением того, что эти два кода различаются следующим образом:

struct tm time; // first code

против

tm time = {}; // second code

СЕЙЧАС, это то, что я нашел очень запутанным. Первый код и второй код дают одинаковый ответ на моей консоли. Я проверил тип результата (days[time.tm_wday]), выполнив также typeid(days[time.tm_wday]).name(), и оба ответа кажутся одинаковыми.

Однако при отправке на веб-сайт Kattis он принимает только второй и не принимает первый.

Теперь, может ли кто-нибудь сказать мне, что мне здесь не хватает? Почему он принимает только одно против другого? Большое спасибо!

РЕДАКТИРОВАТЬ: Немного информации о Каттисе: будет вопрос, который вам придется решить с помощью программирования. Затем он сверяет ваш ответ с их ответом. Если ваша программа выдает одинаковые ответы, она «принимает» ваше решение. Если отличается, то нет.

Например, допустим, вопрос состоит в том, чтобы вычислить площадь квадрата. Он дает пару примеров со значениями.

пример) Случай 1: (ввод: 5, вывод: 25).

Если ваша консоль выводит 25 при вводе 5, то она «принимает» ваше решение. Если он выводит какое-то случайное число, например 10, то он не принимается.

Дело в том, что моя программа выводит точно такие же значения:

Выходы первого кода: Четверг. Вывод второго кода: Четверг и т.д. Однако "правильным" считается только один.


person A. Park    schedule 29.05.2018    source источник
comment
Что вы подразумеваете под принимает?   -  person    schedule 30.05.2018
comment
Первый вариант неправильно инициализирует tm, поэтому вы получаете неопределенное поведение.   -  person user7860670    schedule 30.05.2018
comment
@NeilButterworth Я добавил немного информации о Каттис   -  person A. Park    schedule 30.05.2018
comment
@VTT Первый и второй выводят одну и ту же строку.   -  person A. Park    schedule 30.05.2018


Ответы (1)


В игре есть два отличия:

struct tm time; // (1)

против

tm time = {}; // (2)

1 struct

В C имя составного типа включает ключевое слово struct, здесь "struct tm". В C++ достаточно имени типа, здесь "tm"; но он может иметь префикс struct для совместимости. Подробнее об этом: Разница между "struct" и "typedef struct" в C++?

Итак, что касается ключевого слова struct, на самом деле разница только косметическая.

2. Инициализация

(1) определяет переменную time типа tm. Поскольку tm является POD, это не инициализирован. Использование неинициализированного значения обычно приводит к неопределенному поведению.
(2) определяет и инициализирует список переменную time типа tm. Это, в свою очередь, нуль-инициализирует tm, и поведение программы четко определено.

Подробнее об этом: Что означают следующие фразы в C++: нулевая инициализация, инициализация по умолчанию и значение?

Почему это имеет значение?

Неполная инициализация time и последующий вызов mktime(&time); приводит к неопределенным действиям. Все может случиться. Это может быть разным каждый раз, когда вы запускаете свою программу, это может зависеть от конкретного используемого компилятора, библиотек, с которыми он связан, ОС, оборудования, чего угодно, всего. Он также может работать так, как ожидалось. Подробнее об этом: Неопределенное, неопределенное и определяемое реализацией поведение.

Я подозреваю, что программа случайно работает в вашей среде, но не работает на цели.

person YSC    schedule 29.05.2018
comment
struct tm — это не POD, а структура. Тем не менее, без определенного конструктора ваше утверждение о том, что он не инициализирован, верно, и суть вопроса ОП. - person jwm; 30.05.2018
comment
@jwm, почему вы думаете, что структуры не могут быть POD? тип класса POD – это тип класса (класс/структура/объединение), который является тривиальным, стандартным макетом и не имеет нестатических членов, не относящихся к POD. tm абсолютно соответствует этому определению. Ответ ссылается на это же определение POD, кстати. И без определенного конструктора это не проблема. Тип, не относящийся к POD, который не имеет пользовательских конструкторов, будет инициализирован выражением T t; с использованием конструктор по умолчанию. - person monkey0506; 30.05.2018
comment
Поправляя мой комментарий выше, обратите внимание, что T t; будет вызывать сгенерированный компилятором конструктор T(), но он не будет инициализировать члены встроенных типов (например, int элементы данных). - person monkey0506; 30.05.2018