Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!
Шрифт:
Интервал:
Закладка:
void clean_up_mess()
{
ts.ignore(print);
}
Обработка ошибок всегда является сложной. Она требует постоянного экспериментирования и тестирования, поскольку крайне трудно представить заранее, какая ошибка может возникнуть в ходе выполнения программы. Защита программы от неправильного использования всегда представляет собой очень сложную задачу. Дилетанты об этом никогда не беспокоятся. Качественная обработка ошибок — один из признаков профессионализма.
7.8. Переменные
Поработав над стилем и обработкой ошибок, можем вернуться к попыткам улучшить функциональные возможности калькулятора. Мы получили вполне работоспособную программу; как же ее улучшить? Во-первых, необходимо ввести переменные. Использование переменных позволяет лучше выражать более длинные вычисления.
Аналогично для научных вычислений хотелось бы иметь встроенные имена, такие как pi и e, как в научных калькуляторах. Переменные и константы — основные новшества, которые мы внесем в калькулятор. Это коснется многих частей кода. Такие действия не следует предпринимать без весомых причин и без достаточного времени на работу. В данном случае мы вносим переменные и константы, поскольку это дает возможность еще раз проанализировать код и освоить новые методы программирования.
7.8.1. Переменные и определения
Очевидно, что для работы с переменными и константами программа-калькулятор должна хранить пары (имя, значение) так, чтобы мы имели доступ к значению по имени. Класс Variable можно определить следующим образом:
class Variable {
public:
string name;
double value;
Variable (string n, double v) :name(n), value(v) { }
};
Член класса name используется для идентификации объекта класса Variable, а член value — для хранения значения, соответствующего члену name. Конструктор добавлен просто для удобства.
Как хранить объекты класса Variable так, чтобы их значение можно было найти или изменить по строке name? Оглядываясь назад, видим, что на этот вопрос есть только один правильный ответ: в виде вектора объектов класса Variable.
vector<Variable> var_table;
В вектор var_table можно записать сколько угодно объектов класса Variable, а найти их можно, просматривая элементы вектора один за другим. Теперь можно написать функцию get_value(), которая ищет заданную строку name и возвращает соответствующее ей значение value.
double get_value(string s)
// возвращает значение переменной с именем s
{
for (int i = 0; i<var_table.size(); ++i)
if (var_table[i].name == s) return var_table[i].value;
error("get: неопределенная переменная", s);
}
Этот код действительно прост: он перебирает объекты класса Variable в векторе var_table (начиная с первого элемента и продолжая до последнего включительно) и проверяет, совпадает ли их член name c аргументом s. Если строки name и s совпадают, функция возвращает член value соответствующего объекта. Аналогично можно определить функцию set_value(), присваивающую новое значение члену value объекта класса Variable.
void set_value(string s, double d)
// присваивает объекту класса Variable с именем s значение d
{
for (int i = 0; i<var_table.size(); ++i)
if (var_table[i].name == s) {
var_table[i].value = d;
return;
}
error("set: неопределенная переменная", s);
}
Теперь можем считать и записывать переменные, представленные в виде объектов класса Variable в векторе var_table. Как поместить новый объект класса Variable в вектор var_table? Как пользователь калькулятора должен сначала записать переменную, а затем присвоить ей значения? Можно сослаться на обозначения, принятые в языке С++.
double var = 7.2;
Это работает, но все переменные в данном калькулятора и так хранят значения типа double, поэтому явно указывать этот тип совершенно не обязательно. Можно было бы написать проще.
var = 7.2;
Что ж, возможно, но теперь мы не можем отличить определение новой переменной от синтаксической ошибки.
var1 = 7.2; // определение новой переменной с именем var1
var1 = 3.2; // определение новой переменной с именем var2
Ой! Очевидно, что мы имели в виду var2 = 3.2; но не сказали об этом явно (за исключением комментария). Это не катастрофа, но будем следовать традициям языков программирования, в частности языка С++, в которых объявления переменных с их инициализацией отличаются от присваивания. Мы можем использовать ключевое слово double, но для калькулятора нужно что-нибудь покороче, поэтому — следуя другой старой традиции — выбрали ключевое слово let.
let var = 7.2;
Грамматика принимает следующий вид:
Вычисление:
Инструкция
Печать
Выход
Инструкция вычисления
Инструкция:
Объявление
Выражение
Объявление:
"let" Имя "=" Выражение
Вычисление — это новое правило вывода в грамматике. Оно выражает цикл (в функции calculate()), который позволяет выполнять несколько вычислений в ходе одного сеанса работы программы. При обработке выражений и объявлений это правило опирается на правило Инструкция. Например, инструкцию можно обработать следующим образом:
double statement()
{
Token t = ts.get();
switch (t.kind) {
case let:
return declaration();
default:
ts.putback(t);
return expression();
}
}
Вместо функции expression() в функции calculate() можем использовать функцию statement().
void calculate()
{
while (cin)
try {
cout << prompt;
Token t = ts.get();
while (t.kind == print) t=ts.get(); // игнорируем "печать"
if (t.kind == quit) return; // выход
ts.putback(t);
cout << result << statement() << endl;
}
catch (exception& e) {
cerr << e.what() << endl; // выводим сообщение об ошибке
clean_up_mess();
}
}
Теперь необходимо написать функцию declaration(). Что следует сделать? Нужно убедиться, что после ключевого слова let следует Имя, а за ним — символ = и Выражение. Именно это утверждает грамматика. Что делать с
Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.
Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.
- 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
- 2. Просьба отказаться от оскорблений, угроз и запугиваний.
- 3. Просьба отказаться от нецензурной лексики.
- 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.
Надеемся на Ваше понимание и благоразумие. С уважением, администратор knigkindom.ru.
Оставить комментарий
-
Гость Татьяна24 сентябрь 22:20 Как то не очень... Невеста по ошибке. Я не дам тебе развод - Майя Линн
-
Римма24 сентябрь 21:52 Почему главные героинитпкие идиотки? И сюжет не плохой, и написано хорошо. Но как героиня - так дура дурой.... Хозяйка маленького дома, или Любимая для дракона - Кира Рамис
-
Римма20 сентябрь 12:27 Много ненужных пояснений и отступлений. Весь сюжет теряет свою привлекательность. Героиня иногда так тупит, что читать не... Хозяйка приюта для перевертышей и полукровок - Елена Кутукова