Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

и не прекращать работу, пока пользователь не введет строку

~~
.

Входные данные для калькулятора вводятся с клавиатуры. Это затрудняет тестирование: каждый раз, внося улучшение, мы должны напечатать множество контрольных примеров (каждый раз заново!), чтобы убедиться, что программа по-прежнему работает. Было бы лучше, если бы контрольные примеры где-то хранились и вызывать их одной командой. Некоторые операционные системы (в частности, Unix) упрощают эту задачу, позволяя потоку

cin
считывать данные из файла без модификации программы, а потоку
cout
— направлять данные в файл. В других случаях мы должны модифицировать программу так, чтобы она использовала файл (подробнее об этом — в главе 10).

Рассмотрим примеры.

1+2; q

1+2 q

Мы хотели бы вывести результат (

3
) и выйти из программы. Забавно, что строка

1+2 q

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

1+2; q

вызывает ошибку Ожидается первичное выражение. Где следует искать эту ошибку? Конечно, в функции

main
, где обрабатываются символы ; и q. Мы добавили инструкции “печать” и “выход” просто для того, чтобы поскорее получить работающий вариант калькулятора (см. раздел 6.6), а теперь расплачиваемся за эту поспешность. Рассмотрим еще раз следующий фрагмент:

double val = 0;

while (cin) {

cout << "> ";

Token t = ts.get;

if (t.kind == 'q') break;

if (t.kind == ';')

cout << "= " << val << '\n';

else

ts.putback(t);

val = expression;

}

Если обнаруживаем точку с запятой, то вызываем функцию

expression
, не проверяя символ
q
. Эта функция в первую очередь ищет вызов функции
term
, которая вызывает функцию
primary
, обнаруживающую символ q. Буква q не является первичным выражением, поэтому получаем сообщение об ошибке. Итак, после тестирования точки с запятой мы должны обработать символ q. В этот момент мы почувствовали необходимость несколько упростить логику, поэтому окончательный вариант функции
main
выглядит так:

int main

try

{

while (cin) {

cout << "> ";

Token t = ts.get;

while (t.kind == ';') t=ts.get; // считываем ';'

if (t.kind == 'q') {

keep_window_open;

return 0;

}

ts.putback(t);

cout << "= " << expression << endl;

}

keep_window_open;

return 0;

}

catch (exception& e) {

cerr << e.what << endl;

keep_window_open("~~");

return 1;

}

catch (...) {

cerr << "exception \n";

keep_window_open("~~");

return 2;

}

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

7.4. Отрицательные числа

Проверив калькулятор, легко убедиться, что он не слишком элегантно обрабатывает отрицательные числа. Например, выражение

–1/2

является ошибочным.

Для того чтобы калькулятор работал корректно, мы должны были бы написать

(0–1)/2

Однако это неприемлемо.

Обычно такие проблемы выявляются на поздних этапах отладки и тестирования. Только тогда можно увидеть, что на самом деле делает программа, и получить информацию, позволяющую уточнить исходные идеи. Планируя проект, целесообразно сэкономить время и извлечь выгоду из наших уроков. Очень часто первая версия поставляется пользователям без необходимых уточнений из-за напряженного расписания и жесткой стратегии управления, которая не позволяет вносить исправления в спецификацию на поздних этапах разработки. Поздние добавления — это кошмар менеджера. На самом деле, когда программа уже достаточно работоспособна, но еще не готова к поставке, еще не поздно внести дополнения; это самый первый момент, когда можно учесть опыт ее использования. Реалистичное расписание должно учитывать это обстоятельство.

В данном случае необходимо внести исправления в грамматику, чтобы предусмотреть унарный минус. На первый взгляд легче всего внести исправления в пункт Первичное выражение. Сейчас он выглядит так:

Первичное выражение:

Число

"("Выражение")"

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

Первичное выражение:

Число

  • Читать дальше
  • 1
  • ...
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: