Чтение онлайн

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

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;

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

Live-rpg. эволюция-3

Кронос Александр
3. Эволюция. Live-RPG
Фантастика:
боевая фантастика
6.59
рейтинг книги
Live-rpg. эволюция-3

Пушкарь. Пенталогия

Корчевский Юрий Григорьевич
Фантастика:
альтернативная история
8.11
рейтинг книги
Пушкарь. Пенталогия

Хроники разрушителя миров. Книга 8

Ермоленков Алексей
8. Хроники разрушителя миров
Фантастика:
фэнтези
5.00
рейтинг книги
Хроники разрушителя миров. Книга 8

Адъютант

Демиров Леонид
2. Мания крафта
Фантастика:
фэнтези
6.43
рейтинг книги
Адъютант

Эфир. Терра 13. #2

Скабер Артемий
2. Совет Видящих
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эфир. Терра 13. #2

Кодекс Крови. Книга VI

Борзых М.
6. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VI

Измена

Рей Полина
Любовные романы:
современные любовные романы
5.38
рейтинг книги
Измена

Я – Орк. Том 2

Лисицин Евгений
2. Я — Орк
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я – Орк. Том 2

Законы Рода. Том 2

Flow Ascold
2. Граф Берестьев
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 2

Корпулентные достоинства, или Знатный переполох. Дилогия

Цвик Катерина Александровна
Фантастика:
юмористическая фантастика
7.53
рейтинг книги
Корпулентные достоинства, или Знатный переполох. Дилогия

Тринадцатый

NikL
1. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
6.80
рейтинг книги
Тринадцатый

Темный Патриарх Светлого Рода

Лисицин Евгений
1. Темный Патриарх Светлого Рода
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода

Раб и солдат

Greko
1. Штык и кинжал
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Раб и солдат

Волк 5: Лихие 90-е

Киров Никита
5. Волков
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Волк 5: Лихие 90-е