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

  Юрий  | 

    | 

  Обновл. 10 Апр 2019  | 

 14039

 ǀ   38 

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

Теория

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

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

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

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

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

Задание №1


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

Ответ №1

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

Задание №2

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

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

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

   Число Пи.

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

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

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

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

Ответ №2

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

   bool.

   const double.

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

   float.

   int32_t.

   char.

Задание №3


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

Например:

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

Подсказка №1: Вы можете использовать ветвление 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.

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

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

Ответ №4

Файл constants.h:

Файл main.cpp:

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


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

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

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

  1. Аватар neuro75:

    Здравствуйте, Юрий!
    Спасибо за Ваш курс. До него начинал читать ряд широко рекомендуемых в сообществе самоучителей, нигде предмет не раскрыт так толково и доходчиво!
    По теме: в 28 уроке Вы рекомендуете использовать uniform инициализацию переменных, а в примерах почти везде используете прямую (к примеру,- константа гравитации в constants.h ответа на 4 вопрос теста). Как более правильно?

  2. Аватар zvezdonom:

    Переработал и дополнил программу на задание 4.
    Отдельно в файл calculate.cpp вынесены промежуточные функции.
    Добавлен ввод пользователем шага по времени.
    Использовался цикл while, чтобы вычислять любое количество шагов.

    calculate.h

    constants.h

    calculate.cpp

    main.cpp

    PS. Писал в Qt Creator-е.

  3. Аватар Cerberus:

    Несколько неудачные примеры во втором задании, и вот почему:

    — Цена акции. Тем, кому приходится работать с финансами, уже давно вдалбливают: хранишь где-то деньги — никаких float, только decimal (т.е. с фиксированной точкой) или его эмуляция на целых числах. Так-то понятно, что в диапазон float она должна вписаться, но тем не менее — bad practiсe.
    — Количество морганий — тут претензия только к формулировке: не "ответ в миллионах" (так получается, что ответ — это количество миллионов морганий, а тогда правильный тип — опять же decimal или хотя бы double), а "значение ответа — порядка нескольких миллионов" или что-то в этом духе.

    Впрочем, скорее всего, это придирки с высоты других языков 🙂

  4. Аватар Булат:

    Вот мой вариант, как вам?

  5. Аватар Геннадий:

    Юрий, здравствуйте!
    Подскажите, а такое решение правильно?
    Результат выводит такой — какой и требовался.

    С уважением Геннадий.

  6. Аватар Алексей:

    А, ну да, спасибо за задачку с оператором ветвления, которому не учили, спасибо класс. Тоже самое что школьнику который только выучил цифры сразу дать задание на таблицу умножения =)))

    1. Аватар Cerberus:

      Его разве в главе про тип boolean не было?

  7. Аватар Avraam:

    объясните пожалуйста почему не работает мой код

    1. Аватар fYm:

      Поменяй в самом начале "int" на "double"

  8. Аватар Alexey:

    Вот такой код, не ограничен 5 секундами, если задана большая высота. Если мяч долетит до земли вычисления закончатся.

  9. Аватар Вячеслав:

    Эксперементировал с именами функций в 4-м задании вот что получилось, но главное все работает!

  10. Аватар Вячеслав:

    в 3-м задании все сделал правильно сверился с ответом, но все равно он работает как калькулятор и считает со всеми операторами, а должен только с +

    1. Аватар Юра:

      Немного не понятна ваша проблема. Он выводит все результаты независимо от введенного оператора?

      1. Аватар Вячеслав:

        По заданию программа должна работать только с + , а -, * и / должна игнорировать, но работает со всеми операторами, как в простом калькуляторе

        1. Аватар Дмитрий:

          Читайте внимательно задание. Программа должна игнорировать все знаки, кроме +,-,*,/
          Суть в том, чтобы выполнить одну арифметическую операцию в зависимости от введенного знака(суммирование, вычитание, умножение, деление).

  11. Аватар Andrey:

    Доброго времени суток.
    Пробовал выполнить задание 4.
    Запрос высоты — сделал.
    Требуемую ф-цию, которая будет определять высоту мячика, — сделал.
    По всей (моей) логике следующим этапом должен быть пересчет этой самой высоты, опираясь на время (секунды) и предыдущие результаты. Ну т.е. какая высота будет на следующей секунде, потом еще на одной и т.д.
    Логика подсказывает, что нужно использовать циклы. Но в данном курсе они будут аж в 5-й главе, а из левой литературы я о них узнал пока только то, что они существуют 🙂
    Как без них сделать — не додумался. "Магически" определять секунды сразу в аргументы функции ведь нельзя, это я запомнил. Но как их правильно объявить и посчитать — я еще не знаю.

    Полез смотреть, как же оно реализовано в ответе (до этого подсматривал ток формулу, честное слово :)). В итоге запутался в последних двух ф-циях.. 🙁
    Последняя ф-ция нужна только для того, что бы передать введенную высоту башни и "магическую" секунду одним махом во все остальные, где это нужно? Словно ф-ция, которая собирает в кучу все остальные и заставляет их работать как надо?)
    Себе их скопипастил (с заменой переменных и т.д. на мои), вроде программа работает как должна. Но что-то мне в ней кажется все равно не правильным…
    В общем и целом считаю, что с заданием не справился (все таки пол программы (последние 2 ф-ции) нагло скомунизжено) 🙁

    Вот пример "моей" программы.
    constants.h

    main.cpp

  12. Аватар Роман:

  13. Аватар Евгений:

    Добрый день! Спасибо огромное за статьи! Стараюсь усложнить себе каждое задание по возможности, вот в последнем решил зациклить весь процесс до двух исходных( достижение земли, указание пользователем любой высоты и времени падения).
    Понимаю что код кривоват, с удовольствием услышал бы как его можно облегчить)

    1. Аватар Дмитрий:

      Используйте цикл while для определения оставшейся высоты (если высота меньше 0, то "прилетели"). В таком случае, шагом цикла должно быть количество секунд (в данном случае "считать каждую 1 секунду"). Пример моей программы (вводится начальная высота и шаг в секундах):

  14. Аватар Алексей:

  15. Аватар Алексей:

  16. Аватар Максим:

  17. Аватар Игорь...:

    Почему ранее ничего не упоминалось по поводу операторов (не)равенства? Про "==" сказали. А про ">" и "<" ничего. Я хоть и знал о них, но пытался выполнить задание на основании знаний, полученных из предыдущих уроков.
    calculateAndPrintHeight(initialHeight, 0) — это значит, что переменная seconds (вторая по счёту) в этой функции принимает второй параметр указанный во время вызова этой функции? Об этом тоже ничего не говорилось… А ведь всё кроется как раз в этих мелочах…
    А ответы вообще повеселили с их циклами… За это можно дать пирожок, но на данном этапе курса, я не должен знать о них…

  18. Аватар Илья:

    Здравствуйте! Во-первых, спасибо Вам большое за Ваши труды!=)
    Во-вторых, извините, не знаю, как копировать программу, чтобы она отображалась, как у вас.
    Буду очень благодарен, если Вы сможете прокомментировать мой код. Я сначала немного не так понял задание и хотел, чтобы программа в случае, если мяч достиг земли ранее 5 секунд, дальше не выдавала строчку на каждую секунду, что мяч лежит. Смутила надпись "дальше мячику падать нельзя" =)) Потом перечитал, понял, что всё таки программа должна выводить результат на каждой секунде, сделал. Но закралась идея сделать и так, как понял изначально (тем более, что это как то более логично, мне кажется=) ).
    Дописал программу не дома, пришлось доделывать через онлайн-компилятор, поэтому отсутствует заголовочный файл, константу вбил в основном файле.
    Вот, собственно, программа:

    И ещё один вопрос: подскажите, почему в примере решения 4-ой задачи используются "магические" числа в головной функции для передачи в Callee значение времени.
    Заранее большое спасибо!

    1. Юрий Юрий:

      Привет. То, что строчки программа не выводит, когда мяч находится уже на земли, а 5 секунд не прошли — это хорошо у тебя сделано. Насчет магических чисел — для этого примера подойдет их использование, так как программа не сложная, но то, что ты использовал переменную — это выглядит сложнее + больше повторяющегося кода (это не ошибка, а просто замечание), но такой вариант также вполне уместен в контексте данной программы — это то, к чему можно еще придраться, а так реализация у тебя реально хорошая 🙂

  19. Аватар Бенито:

    Вот такой вариант. А вообще почитав комменты понял, что с "i++" в данном случае лучше, чтобы строчки не плодить.

  20. Аватар artem:

    Тут можно написать любую высоту и покажется сколько секунд будет падать объект и на какой высоте будет на каждой из них

    1. Юрий Юрий:

      У меня были проблемы, программа не запускалась. Сейчас запускается, вижу, всё хорошо.

      1. Аватар artem:

        Как видите для имен переменных я использую только 1-2 символа, но в ваших примерах(почти) все переменные названы словом, нужно ли называть переменные словами, лучше ли от этого читается код, и вообще есть ли разница в этом?

        1. Юрий Юрий:

          Если вам удобно читать код с названиями переменных в 1-2 символа — используйте такие имена. Названия переменных — это дело вкуса каждого отдельно и на выполнение самого кода/программы никак не влияет.

  21. Аватар Александр:

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

    1. Юрий Юрий:

      У вас есть пример в статье, по нему можете ориентироваться. Для задания, которое выполняется несколько раз, следует написать отдельную функцию. Одна функция должна выполнять одно задание, детальнее о разработке программ и логики их написания читайте здесь. Главный принцип, который использован в 4 задании — деление одного сложного задания на несколько легких.

    2. Аватар Александр:

      И еще не могу понять что мы делаем в функции
      void calculateAndPrintHeight.
      И почему нигде не используется currentHeight, куда она тогда передается? Как программа узнает текущее положение мяча?

      1. Юрий Юрий:

        В функции main() мы вызываем первый раз функцию calculateAndPrintHeight(). В calculateAndPrintHeight() вызывается calculateHeight(initialHeight, seconds), которая возвращает currentHeight. Затем этот currentHeight, который присваивается переменной height в функции calculateAndPrintHeight() выводится вместе с seconds.

        Затем в main() второй раз вызывается функция calculateAndPrintHeight(). В ней уже seconds имеет значение 1, поэтому в calculateHeight() мы получим другое значение (currentHeight).

        Потом в main() третий раз вызывается функция calculateAndPrintHeight(). В ней уже seconds имеет значение 2, поэтому в calculateHeight() мы получим опять другое значение (currentHeight), так как в расчете currentHeight участвует переменная seconds, которая с каждым новым вызовом calculateAndPrintHeight() в функции main() — меняется.

        И так и работает эта программа.

  22. Аватар Anton:

    Приветствую, можно критику по поводу 4-ого задания услышать, но не сильно пламенную? По мне код вроде меньше, по крайней мере я не так сильно теряюсь, глядя на множество букв и символов.
    Код в myConstants.h следующий:

    Код в .cpp следующий:

    1. Юрий Юрий:

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

      Т.е. ваше решение — это простое, понятное и достаточно удобное. Но в перспективе оно плохое (поддержка, модификации и т.д.).

      И еще одна проблема в вашем коде: у вас указывается минусовая высота (если взять высоту 100м и 5 секунд, то на 5-ой секунде у вас будет -22.5 meters. Чтобы этого не было — нужно добавить проверку:

      Готовая программа с проверкой:

  23. Аватар Александр:

    ИМХО, в задании №2 на первый вопрос лучше ответить uint8_t (врядли у человека будет отрицательный возраст или ему будет более 255 лет).
    Да, я читал, что беззнаковые переменные лучше не использовать, но здесь идеальная ситуация их применить.

    1. Юрий Юрий:

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

Добавить комментарий для artem Отменить ответ

Ваш E-mail не будет опубликован. Обязательные поля помечены *