Программирование. Принципы и практика использования C++ Исправленное издание, стр. 104
let y = 2;x+y*2;Чем различаются эти примеры? Посмотрим, что происходит. Проблема в том, что мы небрежно определили лексему
ИмяИмя+Посмотрим на код еще раз. После первой буквы считываем строку в объект класса
string>>x+y*2;Что же сделать вместо этого? Во-первых, мы должны точно определить, что представляет собой имя, а затем изменить функцию
get()aaba1Z12asdsddsfdfdasfdsa434RTHTD12345dfdsa8fsd888fadsfА следующие строки именами не являются:
1aas_s#as*a carЗа исключением отброшенного символа подчеркивания это совпадает с правилом языка С++. Мы можем реализовать его в разделе
defaultget()default: if (isalpha(ch)) { string s; s += ch; while (cin.get(ch) && (isalpha(ch) || isdigit(ch))) s+=ch; cin.putback(ch); if (s == declkey) return Token(let); // ключевое слово let return Token(name,s); } error("Неправильная лексема");Вместо непосредственного считывания в объект
string sss+=chchswhile (cin.get(ch) && (isalpha(ch) || isdigit(ch)) s+=ch;считывает символ в переменную
chget()cinchsget()>>7.8.3. Предопределенные имена
Итак, теперь можем легко предопределить некоторые из них. Например, если представить, что наш калькулятор будет использован для научных вычислений, то нам понадобятся имена
piemain()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;}7.8.4. Все?
Еще нет. Мы внесли так много изменений, что теперь программу необходимо снова протестировать, привести в порядок код и пересмотреть комментарии. Кроме того, можно было бы сделать больше определений. Например, мы “забыли” об операторе присваивания (см. упр. 2), а наличие этого оператора заставит нас как-то различать переменные и константы (см. упр. 3). Вначале мы отказались от использования именованных переменных в калькуляторе. Теперь, просматривая код их реализации, можем выбрать одну из двух реакций.
1. Реализация переменных была совсем неплохой; она заняла всего три дюжины строк кода.
2. Реализация переменных потребовала много работы. Она коснулась каждой функции и внесла новую концепцию в проект калькулятора. Она увеличила размер программы на 45%, а ведь мы еще даже не приступали к реализации оператора присваивания.
Если учесть, что наша первая программа имеет значительную сложность, вторая реакция является правильной. И вообще, это справедливо относительно любого предложения, увеличивающего на 50% размер или сложность программы. В такой ситуации целесообразнее написать новую программу, основанную на предыдущих наработках. В частности, намного лучше создавать программу поэтапно, как мы разрабатывали калькулятор, чем пытаться сделать ее целиком и сразу.