Полученные знания всегда нужно применять на практике, поэтому мы сначала повторим теорию, а затем перейдем к практике.
Теория
Целочисленные типы данных используются для хранения целых чисел. Не забывайте о проблемах деления и переполнения с ними. Используйте целочисленные типы с фиксированным размером.
Типы данных с плавающей точкой используются для хранения вещественных чисел. Не забывайте о проблемах с точностью, ошибках округления и неточном сравнении чисел.
Логический тип данных содержит 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
#include <iostream> double getDouble() { std::cout << "Enter a double value: "; double x; std::cin >> x; return x; } char getOperator() { std::cout << "Enter one of the following: +, -, *, or / "; char op; std::cin >> op; return op; } void printResult(double x, char op, double y) { if (op == '+') std::cout << x << " + " << y << " = " << x + y << '\n'; else if (op == '-') std::cout << x << " - " << y << " = " << x - y << '\n'; else if (op == '*') std::cout << x << " * " << y << " = " << x * y << '\n'; else if (op == '/') std::cout << x << " / " << y << " = " << x / y << '\n'; } int main() { double x = getDouble(); double y = getDouble(); char op = getOperator(); printResult(x, op, y); return 0; } |
Задание №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:
1 2 3 4 5 6 7 8 |
#ifndef CONSTANTS_H #define CONSTANTS_H namespace myConstants { const double gravity(9.8); } #endif |
Файл main.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#include <iostream> #include "constants.h" // Получаем начальную высоту от пользователя и возвращаем её double getInitialHeight() { std::cout << "Enter the initial height of the tower in meters: "; double initialHeight; std::cin >> initialHeight; return initialHeight; } // Возвращаем расстояние от земли после "..." секунд падения double calculateHeight(double initialHeight, int seconds) { // Используем формулу: [ s = u * t + (a * t^2) / 2 ], где u(начальная скорость) = 0 double distanceFallen = (myConstants::gravity * seconds * seconds) / 2; double currentHeight = initialHeight - distanceFallen; return currentHeight; } // Выводим высоту, на которой находится мячик после каждой секунды падения void printHeight(double height, int seconds) { if (height > 0.0) std::cout << "At " << seconds << " seconds, the ball is at height: " << height << " meters\n"; else std::cout << "At " << seconds << " seconds, the ball is on the ground.\n"; } void calculateAndPrintHeight(double initialHeight, int seconds) { double height = calculateHeight(initialHeight, seconds); printHeight(height, seconds); } int main() { const double initialHeight = getInitialHeight(); calculateAndPrintHeight(initialHeight, 0); calculateAndPrintHeight(initialHeight, 1); calculateAndPrintHeight(initialHeight, 2); calculateAndPrintHeight(initialHeight, 3); calculateAndPrintHeight(initialHeight, 4); calculateAndPrintHeight(initialHeight, 5); return 0; } |
Обратите внимание, функция calculateHeight() не выводит высоту на экран (помните о «правиле одного задания»). Мы используем отдельную функцию для вывода.
Задание №4
Основной код:
constants.h
При усовершенствовании программы пришлось разнести расчет данных и вывод их на экран по разным функциям) Наглядно видна разница.
Спасибо Вам большое, Юрий! Этим урокам просто нет равных.
Третье задание. Для каждой задачи свой файл.
input.cpp
input.h
calculate.cpp
calculate.h
output.cpp
output.h
main.cpp
Третье задание:
Файл main.cpp:
Файл inNumber.cpp:
Файл cimbol.cpp:
Файл head.h:
Четвертое задание:
Файл main/cpp:
Файл constanta.h:
Третье задание, нормально?
4 задание
Что скажете?
4-е задание:
FallingBall.h:
BallFallConstants.h:
FallingBall.cpp:
Source.cpp:
3-е задание:
Очень забавляют люди, которые используют для решения четвертой задачи циклы. Тут ведь соль задачи, как я понимаю, именно в том, чтобы решить её только с помощью имеющихся средств, то есть только с тем, что уже было пройдено ранее.
У меня вышел такой вот код, к сожалению, отрицательную высоту все равно показывает, не понимаю, почему так(
constants.h
main.cpp
Уже не актуально но всё же .Проверка в 16 строке не имеет смысла ,bW всегда будет положительная потому что умножение и деление не может сделать число отрицательным .Нужно проверять разницу начальной высоты и расчётной .У вас расчётная высота всегда возвращается и если она больше начальной то возникает минус .Например начальная высота 5 а расчёт вернул 10; 5-10=-5
Всегда актуально, спасибо большое)
Сделал такой код.
constants.h
program.h
main.cpp
Калькулятор
Не понимаю, почему после 3 секунды у меня начинаются отрицательные числа
1) Y в этой программе — не скорость, а значение текущей высоты.
2) Условие в блоке if проверяется 1 раз при выполнении строчки, если в момент срабатывания if условие выполняется — вложенный цикл оттарабанит до конца, потому что внутри цикла ничто не может его прервать (не влияет на счетчик i). Вместо использованной конструкции if + for достаточно одного цикла while, где условием будет высота больше 0, а в теле будет, собственно, эта высота изменяться. Ну или же засунуть if на проверку высоты в тело цикла for (с последующим break), рабочий вариант, но более громоздкий.
3. Зачем вывод функции через инициализацию double h? Исходя из того, как написана функция, достаточно типа void и все.
Вышло как-то так
myConstants.h
main.cpp
у меня так вышло
Ну на самом то деле решение то не правильное. У Вас в задаче сказано x секунд, но решение дано только для 5-ти секунд. К сожалению решение этой задачи без знания цикла for на мой взгляд проблематично (у меня фантазия отказала((). Ниже мой пример реализации при которой плевать на высоту (до тех пор пока не будет переполнения), а так же делает столько шагов сколько надо, не останавливаясь на 5-ом.
Решение:
Спасибо автору статей за его бесценный труд.
Последнее задание с циклом!
https://pastebin.com/grjeADV2
+ там еще заголовочный файл с константой гравитации(не добавлял)
Главное — не сдаваться и ставить перед собой задачи, а не бездумно заучивать материал.
Я по своему реализовал калькулятор
Файл "main.cpp"
——————-
Файл "myConstants.h"
————————-
неплохо, только у Вас в строке 15 есть одна ошибка:
здесь должна быть та переменная, которую мы вводим в консоль (она по итогу вообще не используется)
правильный кусок кода:
Точно, спасибо! Я когда дописал, заметил, что начальную высоту не указал, а к тому времени забыл про введённую переменную.
легко
main cpp:
constants.h:
Юрий, добрый день/вечер.
Совсем было забросил обучение с++, работа и тп. Начала недавно с нуля, чтобы и пробелы залатать.
Признаюсь списал последнюю задачу, покололся тут и запутался впервые. Так вот, не нравилась запись совсем, с этим воидами, поэтому и запутался тогда.
Чуть переписал, но уже и использование ссылок.
Очень странно делать переменные в сигнатуре тип const double&, ведь это простой тип, зачем брать от него ссылку и ставить константу. Ссылка необходима, если мы меняем значение самой переменной, и то, обычно, советуют для этого использовать указатели, чтобы было ясно, что мы меняем значение переменной (кроме тех функций, в которых это и так понятно, что будет изменено значение, например, swap(double&, double&)). В других случаях, обычно, используют ссылку для того, чтобы уменьшить время и память на копирование сложных объектов, но для double или int это выглядит нелепо.
Const тоже, в данном случае, будет лишним (если передавать не как ссылку). Если же как у вас, в виде ссылки, то, конечно, да, необходимо const. Но, все таки, в данном случае, нету абсолютно никакого смысла передавать переменные как ссылки.
Такой вопрос, почему у вас получилась такая последовательность цифр после каждой итерации? Насколько я понял вы используете формулу равноускоренного движения. Так вот.
Если судить по вашему листингу, то происходит следующее.
При первой итерации:
100-((9,8*(0*0))/2=100//тут все понятно.
Вторая итерация:
100-((9,8*(1*1))/2=95.1//тут тоже
Третья итерация:
95.1-((9.8*(2*2))/2=75.5//вот тут я и столкнулся с непониманием.
…………….//Дальше по аналогии, но по итогу получаются совсем не те числа. Я просто накидал на коленке программу с использованием цикла, и у меня получились совсем не так, как у вас. Посему вопрос, может я что-то не так сделал?
У тебя тоже было так?
Башня изначально 100 метров
на 0 секунде — 100
на 1 — 95.1
на 2 — 75.5
на 3 — 31.4
на 4 — на земле
Третья итерация у вас неверна.
Каждый раз нужно отнимать от начальной высоты. а не от той, что получилась на предыдущем цикле.
Не могу понять что не так
Добрый день, получил решение задачи следующим путем. Какие недочеты у этого способа решения?
Файл main.cpp
const.h
Изучаю С++ неделю. Нашел ваш сайт. Спасибо за него. Долго мучал 2 итоговое задание. Долго понимал назначение
void calculateAndPrintHeight(double initialHeight, int seconds).
Потом вроде догнал, что объеденяет между собой функции вывода и расчета, чтобы в main() был вызов только одной. Верно?
Мое решение.
Файл main.cpp:
Файл const.h:
Что не так? :/
Немного полегче сделал.
myConstants.h:
main.cpp:
Вставлю так сказать свои 5 копеек))
EarthConstants.h:
io.h:
io.cpp:
Main.cpp:
я не стал делать в 4 задании подключаемый файл, я убил время на нормальный вывод результатов. Оцените пожалуйста
Здравствуйте! По поводу вашего ответа на 4 задание:
Зачем мы в начале функции main вводим КОНСТАНТУ-параметр Initial height?
Константа или нет, результат выполнения программы не меняется.
Как я понял, прост))
Ну, даже если бы это была переменная, на протяжении всей программы она бы не меняла свое значение, ведь мы ее ввели один раз.
Так зачем же нам делать из нее переменную?
Почти три часа работы и она заработала!!!
Хотела прокатить через условие или цикл (for), но потом внезапно вспомнила про цикл while. Какое облегчение)))
constants.h:
Height.cpp:
Буга-га-га-га )))))
)))))))))))
Здравствуйте, пыталась сделать, чтобы были более разные реакции:
1 секунда - ....
2 секунда -мяч коснулся земли...
стоп
или
1 секунда-....
...
5 секунда....
за 5 секунд мяч так и не коснулся земли...
Вроде работает.
Понимаю, что можно короче с if, но как? (в пределах прошедших уроков). И какие еще замечания?:
Заголовочный файл States.h
Рабочий файл 1GetHeight.cpp
Рабочий файл 2FindBTGheight.cpp
Файл main.cpp
Допустим вот моя прога:
main.cpp
constant.h
В принципе, в моей программе можно после цикла for использовать условие, что если height == 0, то тогда соответсвующее сообщение вывести 🙂
да, теперь понимаю, что есть циклы. Но тогда хотелось в пределах прошедших уроков.
И посторайтесь меньше свободного пространства оставлять, а то код-то больше становится (кол-во строк).
Какие недостатки у такого исполнения 4-го задания, если они есть?
Здравствуйте, Юрий!
Спасибо за Ваш курс. До него начинал читать ряд широко рекомендуемых в сообществе самоучителей, нигде предмет не раскрыт так толково и доходчиво!
По теме: в 28 уроке Вы рекомендуете использовать uniform инициализацию переменных, а в примерах почти везде используете прямую (к примеру,- константа гравитации в constants.h ответа на 4 вопрос теста). Как более правильно?
Привет. Рад, что вам приглянулся этот курс. Я не раз в уроках упоминал, что то, что рекомендуется — может не всегда использоваться в примерах следующих уроков (дабы избежать усложнения подачи материала). На практике же рекомендуется использовать uniform инициализацию, хотя (если честно) сам я не всегда встречаю этот тип инициализации. Этот нюанс не настолько критичен и ещё рассматривается с точки зрения удобства его использования.
Переработал и дополнил программу на задание 4.
Отдельно в файл calculate.cpp вынесены промежуточные функции.
Добавлен ввод пользователем шага по времени.
Использовался цикл while, чтобы вычислять любое количество шагов.
calculate.h
constants.h
calculate.cpp
main.cpp
PS. Писал в Qt Creator-е.
Несколько неудачные примеры во втором задании, и вот почему:
— Цена акции. Тем, кому приходится работать с финансами, уже давно вдалбливают: хранишь где-то деньги — никаких float, только decimal (т.е. с фиксированной точкой) или его эмуляция на целых числах. Так-то понятно, что в диапазон float она должна вписаться, но тем не менее — bad practiсe.
— Количество морганий — тут претензия только к формулировке: не "ответ в миллионах" (так получается, что ответ — это количество миллионов морганий, а тогда правильный тип — опять же decimal или хотя бы double), а "значение ответа — порядка нескольких миллионов" или что-то в этом духе.
Впрочем, скорее всего, это придирки с высоты других языков 🙂
Вот мой вариант, как вам?
Юрий, здравствуйте!
Подскажите, а такое решение правильно?
Результат выводит такой — какой и требовался.
С уважением Геннадий.