Читаем Программирование полностью

 Итак, теперь можем легко предопределить некоторые из них. Например, если представить, что наш калькулятор будет использован для научных вычислений, то нам понадобятся имена pi и e. В каком месте кода их следует определить? В функции main() до вызова функции calculate() или в функции calculate() до цикла. Мы поместим их определения в функцию main(), поскольку они не являются частью каких-либо вычислений.

int main()

try {

  // предопределенные имена:

  define_name("pi",3.1415926535);

  define_name("e",2.7182818284);

  calculate();

  keep_window_open(); // обеспечивает консольный режим Windows

  return 0;

}

catch (exception& e) {

  cerr << e.what() << endl;

  keep_window_open("~~");

  return 1;

}

catch (...) {

  cerr << "exception \n";

  keep_window_open("~~");

  return 2;

}

<p id="AutBody_Root131"><strong>7.8.4. Все?</strong></p>

Еще нет. Мы внесли так много изменений, что теперь программу необходимо снова протестировать, привести в порядок код и пересмотреть комментарии. Кроме того, можно было бы сделать больше определений. Например, мы “забыли” об операторе присваивания (см. упр. 2), а наличие этого оператора заставит нас как-то различать переменные и константы (см. упр. 3). Вначале мы отказались от использования именованных переменных в калькуляторе. Теперь, просматривая код их реализации, можем выбрать одну из двух реакций.

1. Реализация переменных была совсем неплохой; она заняла всего три дюжины строк кода.

2. Реализация переменных потребовала много работы. Она коснулась каждой функции и внесла новую концепцию в проект калькулятора. Она увеличила размер программы на 45%, а ведь мы еще даже не приступали к реализации оператора присваивания.

Если учесть, что наша первая программа имеет значительную сложность, вторая реакция является правильной. И вообще, это справедливо относительно любого предложения, увеличивающего на 50% размер или сложность программы. В такой ситуации целесообразнее написать новую программу, основанную на предыдущих наработках. В частности, намного лучше создавать программу поэтапно, как мы разрабатывали калькулятор, чем пытаться сделать ее целиком и сразу.

Задание

1. Скомпилируйте файл calculator08buggy.cpp.

2. Пройдитесь по всей программе и добавьте необходимые комментарии.

3. В ходе комментирования вы обнаружите ошибки (специально вставленные в код, чтобы вы их нашли). Исправьте их; в тексте книги их нет.

4. Тестирование: подготовьте набор тестовых вводных данных и используйте их для тестирования калькулятора. Насколько полон ваш список? Что вы ищете? Включите в список отрицательные числа, нуль, очень маленькие числа и “странный” ввод.

5. Проведите тестирование и исправьте все ошибки, которые пропустили при комментировании.

6. Добавьте предопределенное имя k со значением 1000.

7. Предусмотрите возможность вычисления функции sqrt(), например sqrt(2+6.7). Естественно, значение sqrt(x) — это квадратный корень из числа x; например sqrt(9) равно 3.

8. Используйте стандартную функцию sqrt(), описанную в заголовочном файле std_lib_facilities.h. Не забудьте обновить комментарии и грамматику.

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

10. Предусмотрите возможность использовать функцию pow(x,i), означающую “умножить x на себя i раз”; например pow(2.5,3) равно 2.5*2.5*2.5. Аргумент i должен быть целым числом. Проверьте это с помощью оператора %.

11. Измените “ключевое слово объявления” с let на #.

12. Измените “ключевое слово выхода” с q на exit. Для этого понадобится строка для кодирования инструкции “выход”, как мы уже делали для инструкции “let” в разделе 7.8.2.

Контрольные вопросы

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

2. Почему выражение “1+2; q”, введенное в программу, не приводит к выходу из нее после обнаружения ошибки?

3. Зачем нам понадобилась символьная константа с именем number?

4. Мы разбили функцию main() на две разные функции. Что делает новая функция и зачем мы разделили функцию main()?

5. Зачем вообще разделять код на несколько функций? Сформулируйте принципы.

6. Зачем нужны комментарии и как они должны быть организованы?

7. Что делает оператор narrow_cast?

8. Как используются символические константы?

9. Почему важна организация кода?

10. Как мы реализовали оператор % (остаток) применительно к числам с плавающей точкой?

11. Что и как делает функция is_declared()?

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже