- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Шрифт:
Интервал:
Закладка:
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 следует Имя, а за ним — символ = и Выражение. Именно это утверждает грамматика. Что делать с

