Россия и Беларусь начали и продолжают войну против народа Украины!

Глава №2. Итоговый тест

  Юрий  | 

  |

  Обновл. 10 Фев 2023  | 

 154502

 ǀ   120 

Полученные знания всегда нужно применять на практике, поэтому мы сначала повторим теорию, а затем перейдем к практике.

Теория

Целочисленные типы данных используются для хранения целых чисел. Не забывайте о проблемах деления и переполнения с ними. Используйте целочисленные типы с фиксированным размером.

Типы данных с плавающей точкой используются для хранения вещественных чисел. Не забывайте о проблемах с точностью, ошибках округления и неточном сравнении чисел.

Логический тип данных содержит 2 значения: true и false.

Символьный тип данных содержит целые числа, которые могут интерпретироваться в символы, соответствующие стандарту ASCII. Будьте осторожны при использовании фактических чисел и цифр, которые используются для представления символов. Также помните о проблемах переполнения.

Используйте спецификатор const для объявления символьных констант вместо использования директив #define. Это безопаснее.

Задание №1


Почему символьные константы лучше литеральных (магических чисел)? Почему использование const лучше использования директив #define?

Ответ №1

Использование литеральных констант (магических чисел) не только усложняет программу, но и затрудняет внесение в нее изменений. Символьные константы лучше, так как они дают понимание того, зачем и почему они используются, а также, если вам еще понадобится внести изменения — достаточно будет внести правки только в объявлении константы, а не искать их по всему коду. Значения констант, объявленных с помощью директивы #define, не отображаются в отладчике, вероятность возникновения конфликта имен у таких констант выше.

Задание №2

Выберите подходящий тип данных для переменных в каждой из следующих ситуаций. Будьте как можно более конкретными. Если ответом является целочисленный тип данных, то используйте соответствующий тип с фиксированным размером (например, int16_t). Если переменная должна быть константной, то так и отвечайте.

   Возраст пользователя.

   Нравится ли определенный цвет пользователю?

   Число Пи.

   Количество страниц в учебнике.

   Цена акций в долларах (дробь присутствует).

   Сколько раз вы моргнули за всю свою жизнь? (Примечание: Ответ исчисляется в миллионах)

   Пользователь выбирает опцию с помощью ввода определенной буквы.

Ответ №2

   int8_t не сможет хранить возраст человека, старше 127. Несмотря на то, что таких случаев в мире единицы (если есть вообще), в будущем это может быть вполне возможным. Так что int16_t здесь подойдет лучше.

   bool.

   const double.

   Так как большинство книг имеют больше 255 страниц, но меньше чем 32767, то int16_t — здесь наилучший вариант.

   float.

   int32_t.

   char.

Задание №3


Напишите следующую программу. Сначала пользователю предлагается ввести 2 числа типа с плавающей точкой (используйте тип double). Затем предлагается ввести один из следующих математических символов: +, -, * или /. Программа выполняет выбранную пользователем математическую операцию между двумя числами, а затем выводит результат на экран. Если пользователь ввел некорректный символ, то программа ничего не должна выводить. Например:

Enter a double value: 7
Enter a double value: 5
Enter one of the following: +, -, *, or /: *
7 * 5 = 35

Подсказка: Вы можете использовать ветвление if для того, чтобы распознать, ввел ли пользователь определенный математический символ (например, +) или нет. Детально об этом читайте в материалах урока №34.

Ответ №3

Задание №4

Это уже немного сложнее. Напишите небольшую программу-симулятор падения мячика с башни. Сначала пользователю предлагается ввести высоту башни в метрах. Не забывайте о гравитации (9,8м/с2) и о том, что у мячика нет начальной скорости (его держат в руках). Программа должна выводить расстояние от земли, на котором находится мячик после 0, 1, 2, 3, 4 и 5 секунд падения. Минимальная высота составляет 0 метров (ниже мячику падать нельзя).

В вашей программе должен быть заголовочный файл constants.h с пространством имен myConstants. В myConstants определите константу для хранения значения силы тяжести на Земле (9.8). В качестве напоминания смотрите урок №37.

Напишите функцию для вычисления высоты мячика через х секунд падения. Используйте следующую формулу: высота мячика над землей = константа_гравитации * x_секунд2/2.

Пример результата выполнения программы:

Enter the initial height of the tower in meters: 100
At 0 seconds, the ball is at height: 100 meters
At 1 seconds, the ball is at height: 95.1 meters
At 2 seconds, the ball is at height: 80.4 meters
At 3 seconds, the ball is at height: 55.9 meters
At 4 seconds, the ball is at height: 21.6 meters
At 5 seconds, the ball is on the ground.

Примечания:

   В зависимости от начальной высоты, мячик может и не достичь земли в течение 5 секунд — это нормально. Мы усовершенствуем эту программу, когда будем рассматривать циклы.

   Символ ^ не является экспонентом в языке C++. В формуле вместо него используйте знак умножения *.

Ответ №4

Файл constants.h:

Файл main.cpp:

Обратите внимание, функция calculateHeight() не выводит высоту на экран (помните о «правиле одного задания»). Мы используем отдельную функцию для вывода.


Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (425 оценок, среднее: 4,87 из 5)
Загрузка...

Комментариев: 120

  1. |Oleg|:

    В задании №3 захотелось поэкспрементировать с делением long double

    после вот такого кода получил следующий результат:

    Enter a double value:
    14.958
    Enter a second double value argument:
    97.1122331423
    Choose arithmetic operation by printing one of the following: +, -, *, or /:
    /
    14.958/97.1122331422999999981 = 0.154027968629676346378

    Конечно же, у меня был «нормальный» путь — создать отдельную переменную для результата деления. И надеяться на компилятор, потому как индекс ld/LD/lD/Ld будет негде поставить — инициализация такой переменной зависит от ввода пользователя…

    когда же я поменял setprecision на 22, то получил следующее:

    14.957999999999999999993/97.112233142299999998082 = 0.15402796862967634637762

    Что же произошло? Если всё правильно понял, то для выражений в cout у нас дефолтная точность double — 16 значащих цифр. И эта точность ‘как-то’ распределяется на два аргумента делимое/делитель.

    У первого 5 верных цифр, у второго 11(первый случай, точность 21). Всё нормально. НО уже во втором случае получается точность 4 + 11 = 15. Или всё-таки пятую цифру первого аргумента нужно считать, а я совсем не понимаю правил округления? Почему компилятор gcc взбесился именно от setprecision(22), а при setprecision(21) — точность long double — выдал вполне обычный, понятный результат?

    Благодарю, если кто-то заморочится с поиском истины, хотя это и не так важно. ))

  2. Valdemar:

    Юра, спасибо тебе за этот чудесный сайт!!!

    Служу сейчас в ЗСУ и в свободное время решил попробовать овладеть новыми знаниями (у меня образование медицинское).

    Дошел до Итогового теста 2-й главы и понял, что не смогу написать 4-е задание без заглядывания в ответы.

    Начал все заново с первого урока.

    Просил чат GPT дать дополнительные задачки по каждой теме.

    В итоге написал 4-е задание без подсказок и, не веря в работоспособность сего творения, нажал на на пуск)

    Как же я радовался, когда все получилось! Программа рабочая, но дай, пожалуйста, обратную связь, что я сделал не удачно?

    Слава Украине!

    constants.h

    main.cpp

    1. Avatar photo Юрий:

      Привет! По коду — бросается в глаза функция result(), которая перегружена «однотипным» кодом. Можно подумать, как избавиться от многочисленных if.

      То, что не всё дается сразу и легко — это нормально, таков процесс обучения не только в программировании, но и в других сферах. Слишком зацикливаться на подобных задачках не стоит, но и пропускать тоже не желательно.

      P.S. А вообще в программировании всегда есть много разных вариантов решения проблемы: одни — удачны, но сложны, другие — простые, но громоздкие, третьи — и сложны и громоздкие и т.д. Задача хорошего программиста состоит в том, чтобы подобрать наиболее удачное из существующих решение конкретной проблемы, учитывая обстоятельства ситуации. Это нелегко 🙂

    2. Vladyslav Grechykhin:

      Это отлично, я тоже начал осваивать С++, будучи экономистом. Много if . Использовать лучше либо switch, либо через цикл (ещё лучше, так как он красиво после каждой итерации тебе выведет остаток после каждой секунды)

      Слава Украине

      1. Valdemar:

        Спасибо за поддержку)

        Но ведь switch и циклы рассматриваются в 5 й главе и я до них не дошел? Или я где-то что-то пропустил?

  3. Владимир:

    Первое задание сделал с помощью добавления функции на получение времени. Костыль с «i<time +1″(цикл на 1 раз меньше выполняется из-за итератора) можно было через while пофиксить, но так тоже работает.

  4. Артём:

    Вот моё решение
    main.cpp

    constants.h

  5. Luffy:

    Добрый вечер! Вот мой код 🙂 все никак не научу себя применять функции, кроме как функции ввода)

  6. Вардан:

    Здравствуйте! Вот моё решение, все ответы совпали, как в примере. Подскажите пожалуйста, чем плох моё решение?

  7. Егор:

    Привет, посмотрел решение автора по заданию 4 и… Ничегошеньки не понял, очень мудреное, сложно читать и понять. Я сделал чуть полегче (по деревенски) и нарушил одно негласное правило. Но все же работает)

  8. Роман:

    Пытался сделать на If, но что то пошло не так. Код не сильно читабельный (У меня была цель — выполнить поставленную задачу со всеми проверками и тд.). Возможно код не оптимизирован, но зато работает (на любую высоту (в пределах double)). 🙂

    main.cpp

    constants.h

    1. Роман:

      Обновленный код (почищен, мелкие fix's). В принципе на этом все, всем удачи 🙂

      1. xshady:

        очень интересные названия функций))

  9. Alex:

    Добрый день!
    Спасибо авторам за такой замечательный ресурс!
    У меня есть вопросы по упр. 4:

    1. Почему в функции double calculateHeight в аргументе мы прописываем double initialHeight, int seconds.
    а в самой функции появляются переменные distanceFallen и currentHeight. Почему их не надо прописывать в имени функции, а initialHeight и seconds нужно прописать.

    2. Почему в main нам потребовалось объявить константой initialHeight?

    3. Почему в main в вызове функции calculateAndPrintHeight у нас указан аргумент initialHeight, но он разный, хотя мы его объявили константой. Почему нельзя использовать значение currentHeight (хотя, прописал в функции void calculateAndPrintHeight(double currentHeight, int seconds), и затем double height = calculateHeight(currentHeight, seconds); и все равно работает программа (вот как выглядит функция после изменения:

    )
    Спасибо за ответы.

    1. Виталий:

      initialHeight находится в разных областях видимости,  и что бы знать что значение значит подписал одинаково, в моем варианте они разные, чтоб не возникало путаницы..

      Ваш вариант может и рабочий, но возникает вопрос для не опытного откуда это взялось, а так по функциям читается получше, если разные названия а не как у автора одинаковые, долго мучался разбирался пока все понял

  10. myName:

    Как же я ломал голову по поводу передачи расстояния из функции с потерей остатка от деления. Оказалось что тип данных функции всего то нужно было превратить в тип double 😀

    main.cpp

    constants.h

  11. Артем:

    Задание №4. Решения других пользователей мне по какой-то причине кажутся очень сложными, пока разбирался в их коде заболела голова. Сам набросал такой код, кажется, что он куда проще и читабельнее.

    1. Egor:

      Интересно кончено, но только один вопрос: а зачем вообще нужно было добавлять bool boba, если можно в if вписать (bH > 0), что по сути тоже самое? Тот же вопрос к глобальной переменной check, которая по сути нужна ни для чего. Ведь в функции gMetr мы получаем значение, которое затем присваиваем переменной g и посылаем в функцию calcHeight, после чего, зачем-то, делаем это значение глобальным, при том что используется оно в единственной функции, в которой это значение уже и так есть

    2. Нина:

      Извините, пожалуйста, если я выскажу что — то несущественное. Я изучала программирование самостоятельно и для моих научных задач мне хватало навыков, или я осваивала новые. Но мне хотелось некоторого фундаментального взгляда на программирование…. Вот для этого я читаю и использую этот курс….. Что меня напрягает, может не верно, извините…. Но метр, верста, секунда — это не физические величины, а единицы измерения….. Получается, что в Вашей программе Вы ищете единицу измерения….. Извините, я бы не написала, если бы не увидела этого во множестве программ…… Если не трудно, ответьте, в чем я ошибаюсь….

  12. Mari:

    А такой вопрос, обязательно всё расфасовывать по функциям? Просто мне кажется, что на данном этапе изучения гораздо читабельней код, как пример мой, ниже. Я понимаю, что для одного дела одна функция, но создавая подобную сеть для столь малой программы, мне кажется, код излишне запутывается. Прошу высказать альтернативную точку зрения

    1. Egor:

      Я, как любитель модульных программ (как моды для игр), люблю использование функций из-за одной важной детали: эти функции можно модифицировать и\или использовать в других программах. К тому же возможность проверить каждую функцию отдельно от кода бывает полезной (и я уже не говорю про возможность сворачивать функции, в которых ты уверен, в 1 строку (в VisualStudio)).
      Но в целом — да, для небольших программ можно и без функций

  13. nikkutuzov:

    Я сделал четвертое задание так, чтобы можно было проверить любую высоту башни без использования циклов.

    main.cpp:

    myConst.h:

  14. Тим:

    Сколько раз вы моргнули за всю свою жизнь? (Примечание: Ответ исчисляется в миллионах)
    int32_t, зачем нам отрицательная часть) лучше заменить на uint32_t

    1. Александр:

      «Использовать тип unsigned (вместо signed) для получения еще одного бита для представления положительных целых чисел, почти никогда не является хорошей идеей» — Бьёрн Страуструп

      https://ravesli.com/urok-32-fiksirovannyj-razmer-integers-spor-naschet-unsigned/#toc-5

  15. Александр:

    Добрый день, мой вариант

  16. DeniZZka:

    третье задание

    1. Андрей:

      Неверно. Вернее, программа все равно выводит правильный ответ, но в начале строчки есть пробел. Это оттого, что else будет исполняться всегда, за исключением последнего случая(/). Чтобы программа правильно работала, все if-ы кроме первого нужно заменить на else if.

  17. Юлий:

    Задание №4

    Основной код:

    constants.h

    1. Юлий:

      При усовершенствовании программы пришлось разнести расчет данных и вывод их на экран по разным функциям) Наглядно видна разница.
      Спасибо Вам большое, Юрий! Этим урокам просто нет равных.

  18. Антон:

    Третье задание. Для каждой задачи свой файл.

    input.cpp

    input.h

    calculate.cpp

    calculate.h

    output.cpp

    output.h

    main.cpp

  19. ОЛЕГ:

    Третье задание:

    Файл main.cpp:

    Файл inNumber.cpp:

    Файл cimbol.cpp:

    Файл head.h:

  20. ОЛЕГ:

    Четвертое задание:

    Файл main/cpp:

    Файл constanta.h:

  21. Данил:

    Третье задание, нормально?

  22. Oleg:

    4 задание

    Что скажете?

  23. Артурка:

    4-е задание:

    FallingBall.h:

    BallFallConstants.h:

    FallingBall.cpp:

    Source.cpp:

  24. Артурка:

    3-е задание:

  25. Ангелина:

    Очень забавляют люди, которые используют для решения четвертой задачи циклы. Тут ведь соль задачи, как я понимаю, именно в том, чтобы решить её только с помощью имеющихся средств, то есть только с тем, что уже было пройдено ранее.

    У меня вышел такой вот код, к сожалению, отрицательную высоту все равно показывает, не понимаю, почему так(

    constants.h

    main.cpp

    1. Smail:

      Уже не актуально но всё же .Проверка в 16 строке не имеет смысла ,bW всегда будет положительная потому что умножение и деление не может сделать число отрицательным .Нужно проверять разницу начальной высоты и расчётной .У вас расчётная высота всегда возвращается и если она больше начальной то возникает минус .Например начальная высота 5 а расчёт вернул 10; 5-10=-5

      1. Ангелина:

        Всегда актуально, спасибо большое)

    2. Виктор:

  26. Slava:

    Сделал такой код.

    constants.h

    program.h

    main.cpp

  27. Slava:

    Калькулятор

  28. Elaiten:

    Не понимаю, почему после 3 секунды у меня начинаются отрицательные числа

    1. Raimok:

      1) Y в этой программе — не скорость, а значение текущей высоты.
      2) Условие в блоке if проверяется 1 раз при выполнении строчки, если в момент срабатывания if условие выполняется — вложенный цикл оттарабанит до конца, потому что внутри цикла ничто не может его прервать (не влияет на счетчик i). Вместо использованной конструкции if + for достаточно одного цикла while, где условием будет высота больше 0, а в теле будет, собственно, эта высота изменяться. Ну или же засунуть if на проверку высоты в тело цикла for (с последующим break), рабочий вариант, но более громоздкий.
      3. Зачем вывод функции через инициализацию double h? Исходя из того, как написана функция, достаточно типа void и все.

  29. Onium:

  30. Кто-то:

    Вышло как-то так

    myConstants.h

    main.cpp