126 Глава 2
Типичная ошибка программирования 2.16
Забывают включить файл math.h в программы, использующие библиотеку матема -тических функций.
Обратите внимание, что мы объявили переменные amount, principal и rate типа double. Мы сделали это для простоты, поскольку мы имеем дело с дробной частью долларов и нам нужен тип с плавающей запятой. К сожалению, это может вызвать затруднения. Поясним, к каким недоразумениям может приводить использование float или double при представлении суммы долларов (в предположении, что печать осуществляется с setpreci-sion(2)). Две суммы долларов типа float, хранящиеся в памяти, могут иметь значения 14.234 (печатается как 14.23) и 18.673 (печатается как 18.67). Когда эти суммы складываются, результат внутри компьютера получается 32.907, что будет напечатано как 32.91. Таким образом, печать может иметь вид:
14.23 + 18.67
32.91
но пользователь, складывающий эти числа в том виде, в котором они напечатаны, ожидает получить сумму 32.90!
Хороший стиль программирования 2.21
Не используйте переменные типов float и doubie для денежных расчетов. Неточность чисел с плавающей запятой может привести к ошибкам, которые проявятся в итоге в неправильной сумме денег. В качестве упражнения попробуйте использовать для денежных расчетов целые числа. Заметим: библиотека классов С++ позволяетдолж-ным образом осуществлять денежные расчеты.
Оператор вывода
cout « setw(3) « year
« setiosflags(ios::fixed | ios::showpoint)
« setw(21) « setprecision{2) « amount « endl;}
печатает значения переменных year и amount в формате, заданном параметризованными манипуляторами потока setw, setiosflags и setprecision. Обращение setw(3) определяет, что следующая выходная величина будет напечатана с шириной (размером) поля 3, т.е. ее значение будет содержать по крайней мере 3 символьных позиции. Если длина выходной величины менее 3 символов, она по умолчанию будет выравнена в поле по правому символу. Если длина выходной величины более 3, размер поля будет увеличен, чтобы вместить полную величину. Можно использовать обращение setiosflags(ios::left) для того, чтобы задать выравнивание по левому символу.
Остальная часть задания формата в приведенном операторе вывода указывает, что переменная amount должна печататься как значение с фиксированной точкой и с обязательной печатью этой точки (задается выражением setiosflags(ios::fixed | ios::showpoint)) с правым выравниванием в поле размером в 21 символ (задается выражением setw(21)) и с двумя цифрами после десятичной точки (задается выражением setprecision(2)). Мы подробнее рас-
Управляющие структуры 127
смотрим богатые возможности С++ по форматированию ввода-вывода в главе 11.
Заметьте, что вычисление выражения 1.0 + rate, являющегося аргументом функции pow, производится в теле оператора for. В действительности вычисление этого выражения дает одинаковый результат в каждом цикле, так что его повторные вычисления расточительны.
Совет по повышению эффективности 2.3
Избегайте размещать выражения, значение которых не изменяется, внутри цикла. Но даже, если вы сделаете это, то многие современные сложные оптимизирующие компиляторы автоматически разместят подобные выражения вне цикла во время генерации машинного кода.
- 116 Глава 2
- 2.13. Основы повторения, управляемого счетчиком
- 2.14. Структура повторения for (цикл)
- 120 Глава 2
- 122 Глава 2
- 2.15. Пример использования структуры for
- 124 Глава 2
- 126 Глава 2
- 2.16. Структура множественного выбора switch
- Глава 2
- 130 Глава 2
- 132 Глава 2
- 2.17. Структура повторения do/while
- 134 Глава 2
- 2.18. Операторы break и continue
- Глава 2
- 2.19. Логические операции
- 138 Глава 2
- Глава 2
- 2.21. Заключение по структурному программированию
- IfcrpyKTypa (единственный выбор)
- Глава 2
- Глава 2
- 148 Глава 2
- Глава 2
- Глава 2
- Глава 2
- 156 Глава 2
- 158 Глава 2
- 160 Глава 2
- 2.1. А) следование, выбор и повторение, b) if/else. С) управляемым счет чиком или определенным заранее, d) Метку, сигнал, флаг или лож ный сигнал.
- 162 Глава 2
- 164 Глава 2
- 166 Глава 2
- 168 Глава 2
- 170 Глава 2
- 172 Глава 2
- 174 Глава 2
- 176 Глава 2
- 178 Глава 3
- Глава 3
- 3.3. Математические библиотечные функции
- 3.4. Функции
- Глава 3
- 3.5 Определения функций
- 184 Глава 3
- 186 ГлаваЗ
- 3.6. Прототипы функций
- 188 Глава 3
- 3.7. Заголовочные файлы
- 3.8. Генерация случайных чисел
- Глава 3
- 192 Глава 3
- 194 Глава 3
- 3.9. Пример: азартная игра
- Глава 3
- 198 Глава 3
- 3.10. Классы памяти
- 200 Глава 3
- 3.11. Правила, определяющие область действия
- 202 Глава 3
- 204 Глава 3
- 3.12 Рекурсия
- Глава 3
- 6) Значения, возвращаемые после каждого рекурсивного вызова
- 3.13. Пример использования рекурсии: последовательность чисел Фибоначчи
- Глава 3
- 3.14. Рекурсии или итерации
- 212 Глава 3
- Глава 3
- Глава 4
- Глава 5
- Глава 6
- 3.15. Функции с пустыми списками параметров
- 214 Глава 3
- 3.16. Встраиваемые функции