Програмування на C++ часто пов’язане з C, а відповідно — з поняттями швидкодії і малими одиницями часу. На практиці найменшою одиницею часу є наносекунда — максимально можлива точність виміру в звичайних системах. При низькорівневій розробці також оперують мілісекундами (швидкодія алгоритмів) чи мікросекундами (мітки часу в медіа).
Для ознайомлення з цими величинами і їх типовими позначеннями, необхідно розробити алгоритм, який розбиває мітку часу в наносекундах (timestamp) на:
- Дні (d — days)
- Години (h — hours)
- Хвилини (m — minutes)
- Секунди (s — seconds)
- Мілісекунди (ms — milliseconds)
- Мікросекунди (us — microseconds). Латинська u тут заміняє грецьку μ.
- Наносекунди (ns — nanoseconds)
Всі величини мають бути виведені на екран зі своїм суфіксом.
Приклад роботи
Enter the timestamp (ns): 88702401174195007
1026d 15h 33m 21s 174ms 195us 7ns

Вхідні дані на скріншоті.
#include <iostream>
// Для зручності - окремі змінні для дільників кожної величини.
// Це щоб не повторювати один і той самий вираз в коді кілька разів.
// Щоб отримати лише мікросекунди (ms) з часу в наносекундах timestamp),
// потрібно відкинути все до мікросекунд (остача від ділення на дільник мікросекунд - d_us),
// а потім відкинути наносекунди (цілочисельне ділення на дільник наносекунд - d_ns):
// us = timestamp % d_us / d_ns; Цей
// підхід зберігається для всіх значень, окрім днів і наносекунд, вони простіші.
unsigned long long d_ns = 1000; // Дільник наносекунд.
unsigned long long d_us = d_ns * 1000; // Дільник мікросекунд.
unsigned long long d_ms = d_us * 1000; // Дільник мілісекунд.
unsigned long long d_s = d_ms * 60; // Дільник секунд.
unsigned long long d_m = d_s * 60; // Дільник хвилин.
unsigned long long d_h = d_m * 24; // Дільник годин.
int main()
{
unsigned long long int timestamp;
std::cout << "Enter the timestamp (ns): ";
std::cin >> timestamp;
std::cout << timestamp / d_h << "d "
<< timestamp % d_h / d_m << "h "
<< timestamp % d_m / d_s << "m "
<< timestamp % d_s / d_ms << "s "
<< timestamp % d_ms / d_us << "ms "
<< timestamp % d_us / d_ns << "us "
<< timestamp % d_ns << "ns"
<< std::endl;
return 0;
}
Отже, давайте розглянемо разом ваші роботи і обговоримо, що можна покращити. Зараз загальні моменти, які присутні майже в кожній роботі, потім буде огляд кожної роботи окремо.
- Пропоную потроху вивчати Google Style для уніфікації коду, який використовується на переважній більшості проектів https://google.github.io/styleguide/cppguide.html
- Використовуючи using namespace std; ви одразу затягуєте в свій код всі імена з даного неймспейсу. З часом у великому проекті такий підхід може призвести до конфліку імен. Уникнути цього можна, підключаючи лише ті імена, які ви використовуєте:
using namespace std::cout;
using namespace std::cin;
using namespace std::endl;
3. Глобальні змінні то є зло і їх потрібно уникати, якщо це можливо. Але константи можна і варто оголосити глобально. Назва константи повинна починатись з літери k, за якою назва продовжується верблюдом (з великої букви), наприклад: kTimes.
4. Якщо значення змінної не змінюється, вона повинна бути оголошена константою. Константність краще позначати через constexpr, і лише там, де це неможливо, використовувати const. При використанні constexpr константа буде проініціалізована під час компіляції, const дозволяє зробити це в run-time.
5. С++ дозволяє оголошувати кілька змінних одного типу в одному рядку. Але варто уникати цього і кожну змінну оголошувати в окремому рядку.
6. Змінна повинна бути проініціалізована при оголошенні. Завжди задавайте початкове значення змінної для уникнення випадкового використання «сміттєвого значення».
7. Найкращий і найбезпечніший спосіб ініціалізувати змінну це uniform-initialization (фігурні дужки і без знаку присвоєння). В цьому випадку компілятор не буде приводити типи, а видасть помилку, якщо дане значення не співпадає з оголошеним типом. Приклад такої ініціалізації:
int a{-5};
unsigned int b{-5}; // компілятор видасть помилку
unsigned int c = -5; // компілятор видасть попередження
8. Використовуйте типи з плаваючою точкою лише для чисел з плаваючою точкою. В даній задачі у вас задається кількість наносекунд, яка апріорі не можу бути дробом, як і інші величини у вас лише цілочисленні.
9. Позначати тип як беззнаковий (unsigned), якщо діапазон значень даної змінної лише додатні числа і нуль:
unsigned int days{0};
10. Приведення типу зі звуженням (з втратою частини розрядів) свідчить про архітектурну помилку і в С++ не вітається, а за стандартами безпеки взагалі заборонено.
11. Ніколи не використовуйте в С++ конструкції мови С, якщо є С++ аналог. Для приведення типів в 90% підійте static_cast.
12. Використання С макросів в С++ заборонене через порушення безпекових принципів.
13. Використання #define в С++ дозволене лише для підключення платформозалежних бібліотек.
14. Слідкуйте за повідомленнями компілятора. Ви повинні усунути не лише усі повідомлення про помилки (без чого ваша програма і не скомпілюється), але й усі попередження (warning).
Добавить комментарий